Heim > Web-Frontend > js-Tutorial > Hauptteil

Reines natives JS realisiert das Hinzufügen und Löschen von Tabellen

高洛峰
Freigeben: 2017-01-07 10:12:37
Original
1281 Leute haben es durchsucht

Der Firmenpraktikant fragte mich nach dem Hinzufügen und Löschen von Tabellen und es war mit jQuery sehr einfach zu implementieren. Er fragte mich auch, wie ich es ohne jQuery und nur mit js implementieren könne.

Angesichts dieser Situation ist mein üblicher Ansatz „nicht verstehen, sondern unterstützen“.

JQuery wird häufig verwendet und die Leute sind zu faul, aber ich denke, die Schwierigkeit liegt in der IE-Kompatibilität. . .

Wenn Sie nur nach dem Code suchen möchten, können Sie den Analysevorgang überspringen. Der vollständige Code ist am Ende des Artikels angehängt.

Das Folgende ist der Codierungsprozess:

HTML-Strukturcode

Eine grundlegende Tabellenstruktur mit einigen hinzugefügten einfachen Stilen. Drei Schaltflächen entsprechen „Erstellen“, „Löschen“ und „Reserviert“.

<!DOCTYPE HTML> 
<html> 
 <head> 
  <title>table</title> 
  <meta charset=&#39;utf-8&#39; /> 
  <style type="text/css"> 
   table.base{ 
    border-collapse:collapse; 
    text-align: center; 
    border: 1px solid black; 
   }  
   table, tr, td, th{ 
    border: 1px solid black; 
   }    
  </style> 
 </head> 
 <body> 
  <div id="main-content"> 
   <table id="main-table" class="base"> 
    <thead> 
     <tr> 
      <th colspan="3">This is a table for operations by javascript</th> 
     </tr> 
     <tr> 
      <th> 
       <input type="button" value="CREATE" id="cp_btn" onclick="createTr()" /> 
      </th> 
      <th> 
       <input type="button" value="CLEAR" id="cl_btn" onclick="clearTrs()" /> 
      </th> 
      <th> 
       <input type="button" value="GUESS" id="cl_btn"/> 
      </th> 
     </tr> 
    </thead> 
    <tbody> 
    </tbody> 
   </table> 
  </div> 
 </body> 
</html>
Nach dem Login kopieren

Konstruktor (Pseudokonstruktor)

In Betracht gezogen, erstellen Sie ein verstecktes Tr und führen Sie den Erstellungsvorgang basierend auf diesem Tr aus. Um die Gesamtstruktur von HTML nicht zu zerstören, wurde beschlossen, das tr-Objekt über js zu generieren und an die Seite anzuhängen.

Um DOM-Operationen nach dem Laden der Seite auszuführen, platzieren Sie <script> am Ende des Codes vor </body>. </p><p>Um Additions- und Löschvorgänge basierend auf tbody in der Tabelle durchzuführen, können Sie zunächst diese globale Variable deklarieren </p><p>var vTbody = document.getElementById('main-table').getElementsByTagName('tbody ')[0] ; </p><p>Um ein Objekt zu erstellen, können Sie die Methode document.createElement verwenden. </p><p>Objektorientiert programmieren, zuerst den Konstruktor schreiben (eigentlich handelt es sich nicht um ein Standardkonstruktorformat), beginnend mit dem innersten Element. </p><p>Es kann Formularelemente wie Text und Schaltfläche in td geben, also erstellen Sie zunächst eine Eingabekonstruktorfunktion myInput(vId, vClass, vType, vValue, vParent){}</p><p>Hier ist eines Das Kompatibilitätsproblem besteht darin, dass der IE-Kernel setAttribute(class, value) nicht unterstützt und setAttribute(className, value) verwenden muss. Um das Kompatibilitätsproblem zu lösen, können Sie daher </p><p>setAttribute(class,) verwenden. value) für FF und Chrome.</p><p>setAttribute(className, value) für IE</p><p>Hier ist eine andere Möglichkeit .className, der Code lautet wie folgt: </p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false">function myInput(vId, vClass, vType, vValue, vParent) { var vInput = document.createElement(&amp;#39;input&amp;#39;); if(vId) { vInput.setAttribute(&amp;#39;id&amp;#39;, vId); } vInput.setAttribute(&amp;#39;type&amp;#39;, vType); vInput.setAttribute(&amp;#39;value&amp;#39;, vValue); vInput.className = vClass; if(vParent) { vParent.appendChild(vInput); } }</pre><div class="contentsignin">Nach dem Login kopieren</div></div><p> Dann td Objekt und tr Der Konstruktor des Objekts ist ähnlich, der Code lautet wie folgt </p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false">function myTd(vId, vClass, vChild, vParent) { var vTd = document.createElement(&amp;#39;td&amp;#39;); if(vId){ vTd.setAttribute(&amp;#39;id&amp;#39;, vId); } vTd.className = vClass; if(vChild) { vTd.appendChild(vChild); } if(vParent) { vParent.appendChild(vTd); } return vTd; } function myTr(vId, vClass, vChild, vParent) { var vTr = document.createElement(&amp;#39;tr&amp;#39;); if(vId){ vTr.setAttribute(&amp;#39;id&amp;#39;, vId); } vTr.className = vClass; if(vChild) { vTr.appendChild(vChild); } if(vParent) { vParent.appendChild(vTr); } return vTr; }</pre><div class="contentsignin">Nach dem Login kopieren</div></div><p>Neue Zeilenmethode createTr()</p><p>Verbessern Sie nach Abschluss des Konstruktors die Methode createTr() Verfahren. </p><p>Die erwartete Tr-Struktur besteht aus Seriennummer, Textfeld und Bedienschaltfläche. </p><p>Erstellen Sie verwandte Objekte nacheinander. Die Seriennummernspalte muss dynamisch aktualisiert werden. Legen Sie daher zunächst den Klassennamen fest und führen Sie den Sortiervorgang über die Methode durch. </p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false">function createTr() { var vTr = new myTr(null, null, null, vTbody); //序列td var vTdSeq = new myTd(null, &amp;#39;seq&amp;#39;, null, vTr); //文本框td var vTdText = new myTd(null, null, null, vTr); var vInputText = new myInput(null, &amp;#39;td-inp-txt&amp;#39;, &amp;#39;text&amp;#39;, &amp;#39;&amp;#39;, vTdText); //操作按钮td var vTdBtn = new myTd(null, null, null, vTr); var vInputBtnCp = new myInput(null, &amp;#39;td-inp-btn-cp&amp;#39;, &amp;#39;button&amp;#39;, &amp;#39;COPY&amp;#39;, vTdBtn); var vInputBtnDel = new myInput(null, &amp;#39;td-inp-btn-del&amp;#39;, &amp;#39;button&amp;#39;, &amp;#39;DELETE&amp;#39;, vTdBtn); }</pre><div class="contentsignin">Nach dem Login kopieren</div></div><p>Sortiermethode reSequence()</p><p>Erstellen Sie eine dynamische Sortiermethode reSequence(). Es gibt ein Kompatibilitätsproblem unter Firefox, daher wird innerHTML verwendet. Der Code lautet wie folgt: </p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:html;toolbar:false">function reSequence() { var vObj = vTbody.getElementsByClassName(&amp;#39;seq&amp;#39;); for (var i=0, len=vObj.length; i&lt;len; i++) { vObj[i].innerHTML = i+1; } }</pre><div class="contentsignin">Nach dem Login kopieren</div></div><p>Es gibt ein Kompatibilitätsproblem. IE8 und unten unterstützen die Methode getElementsByClassName() nicht. Ich habe online eine Lösung gefunden. </p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">if(!document.getElementsByClassName){ document.getElementsByClassName = function(className, element){ var children = (element || document).getElementsByTagName(&amp;#39;*&amp;#39;); var elements = new Array(); for (var i=0; i&lt;children.length; i++){ var child = children[i]; var classNames = child.className.split(&amp;#39; &amp;#39;); for (var j=0; j&lt;classNames.length; j++){ if (classNames[j] == className){ elements.push(child); break; } } } return elements; }; }</pre><div class="contentsignin">Nach dem Login kopieren</div></div><p>Ich habe versucht, die zu verwenden Prototyp von Object oder HTMLTableSectionElement Fügen Sie diese Methode hinzu, z. B. </p><p>HTMLTableSectionElement.prototype.getElementsByClassName = function(){} </p><p> Leider ist sie nicht implementiert. </p><p>Der geänderte Code ist </p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false">function reSequence() { var vObj = vTbody.getElementsByClassName == null?document.getElementsByClassName(&amp;#39;seq&amp;#39;, vTbody):vTbody.getElementsByClassName(&amp;#39;seq&amp;#39;); for (var i=0, len=vObj.length; i&lt;len; i++) { vObj[i].innerHTML = i+1; } }</pre><div class="contentsignin">Nach dem Login kopieren</div></div><p>Zusätzlich zum Sortieren sind weitere Vorgänge erforderlich, daher erstellen wir in createTr() eine init()-Methode, um die reSequence()-Methoden zentral zu verwalten Die Methode init() wird am Ende der Methode aufgerufen. </p><p>Leerzeilenmethode „clearTrs()“ löschen</p><p>Um ein DOM-Objekt zu entfernen/zerstören, fällt mir als Erstes die Methode „remove()“ ein. Leider gibt es ein Kompatibilitätsproblem mit dem IE-Browser , also verwenden Sie eine einfachere Möglichkeit, innerHTML="" für das Dom-Objekt auszuführen. Der Code lautet wie folgt: </p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false">function clearTrs() { vTbody.innerHTML = &amp;#39;&amp;#39;; }</pre><div class="contentsignin">Nach dem Login kopieren</div></div><p>IE8 meldet einen Fehler: „Unbekannter Ausführungsfehler“. Ich habe Folgendes überprüft, weil die table.innerHTML von IE8 ein schreibgeschütztes Attribut ist, verdammt! Erneut ändern: </p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false">function clearTrs() { while(vTbody.rows.length &gt;0) { vTbody.deleteRow(); } }</pre><div class="contentsignin">Nach dem Login kopieren</div></div><p>Zeilenmethode löschen addBtnDelsListener()</p><p>Als nächstes binden Sie die Methode zum Löschen der aktuellen Zeile an die Schaltfläche DELETE. </p><p>Um das Kompatibilitätsproblem zu lösen, besteht die im Internet angegebene Methode darin, die Methoden addEventListener bzw. attachmentEvent für verschiedene Browser (IE, Nicht-IE) zu verwenden. </p><p>Ich verwende eine andere Lösung :</p><p>obj.onclick = function(){};</p><p>Der Methodenkörper der anonymen Funktion hat die Erfahrungen und Lehren aus der obigen Methode clearTrs() gelernt und verwendet direkt den deleteRow(index ) Methode. </p><p>Zu beachten ist, dass die Anzahl der von thisTr.rowIndex erhaltenen Zeilen um 2 größer ist als die aktuelle Zeile, da sich im Kopf zwei weitere Zeilen befinden. Die aktuelle Anzahl der Indizes ist also = thisTr.rowIndex-vThead.rows.length</p><p>Der Code lautet wie folgt:</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false">function addBtnDelsListener() { var vBtnDels = vTbody.getElementsByClassName == null?document.getElementsByClassName(&amp;#39;td-inp-btn-del&amp;#39;, vTbody):vTbody.getElementsByClassName(&amp;#39;td-inp-btn-del&amp;#39;); for (var i=0, len=vBtnDels.length; i&lt;len; i++) { vBtnDels[i].onclick = function() { var vTr = this.parentElement.parentElement; vTbody.deleteRow(vTr.rowIndex-vTbody.parentNode.getElementsByTagName(&amp;#39;thead&amp;#39;)[0].rows.length); reSequence(); }; } }</pre><div class="contentsignin">Nach dem Login kopieren</div></div><p>Nachdem Sie den Löschvorgang ausgeführt haben, ordnen Sie ihn mithilfe der reSequence()-Methode neu an . </p><p>Fügen Sie gleichzeitig die Methode addBtnDelsListener() zur Methode init() hinzu. </p><p>Zeilenmethode addBtnCpsListener() kopieren</p><p>Sehen Sie sich noch einmal die Schaltfläche KOPIEREN an. Die Methode zum Hinzufügen von Ereignis-Listenern ist dieselbe wie oben. </p><p>Wenn innerHTML nicht schreibgeschützt ist, können Sie Element ein tr-Element und dann newTr.innerHTML=thisTr.innerHTML erstellen. </p><p>Aus Kompatibilitätsgründen müssen einige Änderungen vorgenommen werden. </p><p>Tatsächlich kann das Kopieren als Erstellen einer neuen Zeile betrachtet werden. Der einzige Unterschied besteht darin, dass der Inhalt des Texteingabefelds der neuen Zeile mit dem Inhalt der kopierten Zeile übereinstimmen muss. </p><p>Das ist ganz einfach. Ich kann zuerst die Methode createTr() aufrufen und dann den Wert des Textfelds im letzten Element lastChild so festlegen, dass er der kopierten Zeile entspricht. </p><p>Ich habe die Idee, der Code lautet wie folgt: </p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false">function addBtnCpsListener() { var vBtnCps = vTbody.getElementsByClassName == null?document.getElementsByClassName(&amp;#39;td-inp-btn-cp&amp;#39;, vTbody):vTbody.getElementsByClassName(&amp;#39;td-inp-btn-cp&amp;#39;); for (var i=0, len=vBtnCps.length; i&lt;len; i++) { vBtnCps[i].onclick = function() { createTr(); var vNewTr = vTbody.lastChild; var vTr = this.parentElement.parentElement; vNewTr.getElementsByClassName == null?document.getElementsByClassName(&amp;#39;td-inp-txt&amp;#39;, vNewTr)[0].value = document.getElementsByClassName(&amp;#39;td-inp-txt&amp;#39;, vTr)[0].value:vNewTr.getElementsByClassName(&amp;#39;td-inp-txt&amp;#39;)[0].value = vTr.getElementsByClassName(&amp;#39;td-inp-txt&amp;#39;)[0].value; } } }</pre><div class="contentsignin">Nach dem Login kopieren</div></div><p>Optimierungsänderungen</p><p>Führen Sie einige Optimierungsänderungen durch: </p><p>var elements = neues Array (); </p><p> geändert zu: var elements = [];</p><p> Grund: Es ist besser, [] für Arrays zu verwenden </p><p> vBtnDels[i].onclick = Funktion ändern () in der addBtnDelsListener-Methode {</p><p>修改为:vBtnDels[i].onclick = delTr;</p><p>外部新创建一个函数</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false">function delTr() { var vTr = this.parentElement.parentElement; vTbody.deleteRow(vTr.rowIndex-vTbody.parentNode.getElementsByTagName(&amp;#39;thead&amp;#39;)[0].rows.length); reSequence(); }</pre><div class="contentsignin">Nach dem Login kopieren</div></div><p>原因:Don&#39;t make functions within a loop.</p><p>同理,将addBtnCpsListener中的vBtnCps[i].onclick = function() {</p><p>修改为:vBtnCps[i].onclick = copyTr;</p><p>外部新创建一个函数</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false">&lt;pre code_snippet_id=&quot;139791&quot; snippet_file_name=&quot;blog_20140103_15_6784659&quot; name=&quot;code&quot; class=&quot;javascript&quot;&gt; function copyTr() { createTr(); var vNewTr = vTbody.lastChild; var vTr = this.parentElement.parentElement; vNewTr.getElementsByClassName === null? document.getElementsByClassName(&amp;#39;td-inp-txt&amp;#39;, vNewTr)[0].value = document.getElementsByClassName(&amp;#39;td-inp-txt&amp;#39;, vTr)[0].value: vNewTr.getElementsByClassName(&amp;#39;td-inp-txt&amp;#39;)[0].value = vTr.getElementsByClassName(&amp;#39;td-inp-txt&amp;#39;)[0].value; }</pre> <pre class="brush:php;toolbar:false"></pre> <pre class="brush:php;toolbar:false"></pre></pre><div class="contentsignin">Nach dem Login kopieren</div></div><p>将copyTr()方法中的?:格式修改为if else函数。</p><p>修改为:</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false">function copyTr() { createTr(); var vNewTr = vTbody.lastChild; var vTr = this.parentElement.parentElement; if(vNewTr.getElementsByClassName) { vNewTr.getElementsByClassName(&amp;#39;td-inp-txt&amp;#39;)[0].value = vTr.getElementsByClassName(&amp;#39;td-inp-txt&amp;#39;)[0].value; } else { document.getElementsByClassName(&amp;#39;td-inp-txt&amp;#39;, vNewTr)[0].value = document.getElementsByClassName(&amp;#39;td-inp-txt&amp;#39;, vTr)[0].value; } }</pre><div class="contentsignin">Nach dem Login kopieren</div></div><p>原因:?:预期返回值应该是一个变量or函数,而不应该是一个表达式操作。</p><p>有一点需要注意:js最佳实现经常看到要使用===替换==。但是本示例中的==null,如果替换成===null会在ie8一下版本中出现问题。</p><p>完整代码</p><p>至此,一个完全基于原生JavaScript,并且兼容至IE6的table增删完成了。</p><p>还是想吐槽一下,如果不兼容IE10以下的版本,可以节省50%的代码。如果使用jQuery,又可以节省50%的代码。对于实用主义的我而言,这一过程备受煎熬。不过还是从中有所收益的(违心。。)</p><p>以下为完整代码:</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:html;toolbar:false"><!DOCTYPE HTML> <html> <head> <title>table</title> <meta charset=&#39;utf-8&#39; /> <style type="text/css"> table.base{ border-collapse:collapse; text-align: center; border: 1px solid black; } table, tr, td, th{ border: 1px solid black; } </style> </head> <body> <div id="main-content"> <table id="main-table" class="base"> <thead> <tr> <th colspan="3">This is a table for operations by javascript</th> </tr> <tr> <th> <input type="button" value="CREATE" id="cp_btn" onclick="createTr()" /> </th> <th> <input type="button" value="CLEAR" id="cl_btn" onclick="clearTrs()" /> </th> <th> <input type="button" value="GUESS" id="cl_btn"/> </th> </tr> </thead> <tbody> </tbody> </table> </div> <script type="text/javascript"> if(!document.getElementsByClassName){ document.getElementsByClassName = function(className, element){ var children = (element || document).getElementsByTagName(&#39;*&#39;); var elements = []; for (var i=0; i<children.length; i++){ var child = children[i]; var classNames = child.className.split(&#39; &#39;); for (var j=0; j<classNames.length; j++){ if (classNames[j] == className){ elements.push(child); break; } } } return elements; }; } var vTbody = document.getElementById(&#39;main-table&#39;).getElementsByTagName(&#39;tbody&#39;)[0]; function myInput(vId, vClass, vType, vValue, vParent) { var vInput = document.createElement(&#39;input&#39;); if(vId) { vInput.setAttribute(&#39;id&#39;, vId); } vInput.setAttribute(&#39;type&#39;, vType); vInput.setAttribute(&#39;value&#39;, vValue); vInput.className = vClass; if(vParent) { vParent.appendChild(vInput); } return vInput; } function myTd(vId, vClass, vChild, vParent) { var vTd = document.createElement(&#39;td&#39;); if(vId){ vTd.setAttribute(&#39;id&#39;, vId); } vTd.className = vClass; if(vChild) { vTd.appendChild(vChild); } if(vParent) { vParent.appendChild(vTd); } return vTd; } function myTr(vId, vClass, vChild, vParent) { var vTr = document.createElement(&#39;tr&#39;); if(vId){ vTr.setAttribute(&#39;id&#39;, vId); } vTr.className = vClass; if(vChild) { vTr.appendChild(vChild); } if(vParent) { vParent.appendChild(vTr); } return vTr; } function createTr() { var vTr = new myTr(null, null, null, vTbody); //序列td var vTdSeq = new myTd(null, &#39;seq&#39;, null, vTr); //文本框td var vTdText = new myTd(null, null, null, vTr); var vInputText = new myInput(null, &#39;td-inp-txt&#39;, &#39;text&#39;, &#39;&#39;, vTdText); //操作按钮td var vTdBtn = new myTd(null, null, null, vTr); var vInputBtnCp = new myInput(null, &#39;td-inp-btn-cp&#39;, &#39;button&#39;, &#39;COPY&#39;, vTdBtn); var vInputBtnDel = new myInput(null, &#39;td-inp-btn-del&#39;, &#39;button&#39;, &#39;DELETE&#39;, vTdBtn); init(); } function clearTrs() { while(vTbody.rows.length >0) { vTbody.deleteRow(); } } function init(){ reSequence(); addBtnDelsListener(); addBtnCpsListener(); } function reSequence() { var vObj = vTbody.getElementsByClassName == null? document.getElementsByClassName(&#39;seq&#39;, vTbody): vTbody.getElementsByClassName(&#39;seq&#39;); for (var i=0, len=vObj.length; i<len; i++) { vObj[i].innerHTML = i+1; } } function addBtnDelsListener() { var vBtnDels = vTbody.getElementsByClassName == null? document.getElementsByClassName(&#39;td-inp-btn-del&#39;, vTbody): vTbody.getElementsByClassName(&#39;td-inp-btn-del&#39;); for (var i=0, len=vBtnDels.length; i<len; i++) { vBtnDels[i].onclick = delTr; } } function delTr() { var vTr = this.parentElement.parentElement; vTbody.deleteRow(vTr.rowIndex-vTbody.parentNode.getElementsByTagName(&amp;#39;thead&amp;#39;)[0].rows.length); reSequence(); } function addBtnCpsListener() { var vBtnCps = vTbody.getElementsByClassNamenull == null? document.getElementsByClassName(&#39;td-inp-btn-cp&#39;, vTbody): vTbody.getElementsByClassName(&#39;td-inp-btn-cp&#39;); for (var i=0, len=vBtnCps.length; i<len; i++) { vBtnCps[i].onclick = copyTr; } } function copyTr() { createTr(); var vNewTr = vTbody.lastChild; var vTr = this.parentElement.parentElement; if(vNewTr.getElementsByClassName) { vNewTr.getElementsByClassName(&#39;td-inp-txt&#39;)[0].value = vTr.getElementsByClassName(&#39;td-inp-txt&#39;)[0].value; } else { document.getElementsByClassName(&#39;td-inp-txt&#39;, vNewTr)[0].value = document.getElementsByClassName(&#39;td-inp-txt&#39;, vTr)[0].value; } } </script>

Nach dem Login kopieren

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持PHP中文网!

更多纯原生js实现table表格的增删相关文章请关注PHP中文网!


Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Empfehlungen
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage