Maison  >  Article  >  interface Web  >  Js natif pur réalise l'ajout et la suppression de tables de table

Js natif pur réalise l'ajout et la suppression de tables de table

高洛峰
高洛峰original
2017-01-07 10:12:371285parcourir

Le stagiaire de l'entreprise m'a posé des questions sur l'ajout et la suppression de tables, et c'était très simple à mettre en œuvre avec jQuery. Il m'a également demandé comment l'implémenter sans utiliser jQuery et uniquement en utilisant js.

Face à cette situation, mon approche habituelle est « ne pas comprendre, mais soutenir ».

J'ai beaucoup utilisé jQuery et les gens sont trop paresseux, mais j'ai quand même utilisé js pour implémenter cette opération, je pense que la difficulté réside dans la compatibilité avec IE. . .

Si vous souhaitez simplement rechercher le code, vous pouvez ignorer le processus d'analyse. Le code complet est joint au bas de l'article.

Voici le processus de codage :

Code de structure HTML

Une structure de table de base avec quelques styles simples ajoutés. Trois boutons correspondent à créer, effacer et réservé.

<!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>

Constructeur (pseudo constructeur)

Considéré, créez un tr caché et effectuez l'opération de création basée sur ce tr. Afin de ne pas détruire la structure globale du HTML, il a été décidé de générer l'objet tr via js et de l'ajouter à la page.

Afin d'effectuer des opérations DOM après le chargement de la page, placez 3f1c4e4b6b16bbbd69b2ee476dc4f83a en bas du code avant 36cc49f0c466276486e50c850b7e4956.

Pour effectuer des opérations d'ajout et de suppression basées sur le corps du tableau, vous pouvez d'abord déclarer cette variable globale

var vTbody = document.getElementById('main-table').getElementsByTagName('tbody ')[0] ;

Pour créer un objet, vous pouvez utiliser la méthode document.createElement.

Programmez de manière orientée objet, écrivez d'abord le constructeur (en fait ce n'est pas un format de constructeur standard), en commençant par l'élément le plus interne.

Il peut y avoir des éléments de formulaire tels que du texte et un bouton dans td, alors créez d'abord une fonction de constructeur d'entrée myInput(vId, vClass, vType, vValue, vParent){}

En voici un. Le problème de compatibilité est que le noyau IE ne prend pas en charge setAttribute(class, value) et doit utiliser setAttribute(className, value). Par conséquent, afin de résoudre le problème de compatibilité, vous pouvez utiliser

setAttribute(class,). value) pour FF et Chrome .

setAttribute(className, value) pour IE

Voici une autre façon .className, le code est le suivant :

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); 
 } 
}

Puis td object et tr Le constructeur de l'objet est similaire, le code est le suivant

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; 
}

Nouvelle méthode de ligne createTr()

Une fois le constructeur terminé, améliorez le createTr() méthode.

La structure tr attendue est le numéro de série, la zone de texte et le bouton d'opération.

Créez des objets associés en séquence. La colonne du numéro de série doit être actualisée dynamiquement, alors définissez d'abord le nom de la classe et effectuez l'opération de tri via la méthode.

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); 
}

Méthode de tri reSequence()

Créer une méthode de tri dynamique reSequence() Il y a un problème de compatibilité innerText n'a aucun effet sous Firefox, donc innerHTML est utilisé. Le code est le suivant

function reSequence() { 
 var vObj = vTbody.getElementsByClassName(&#39;seq&#39;); 
 for (var i=0, len=vObj.length; i<len; i++) { 
  vObj[i].innerHTML = i+1; 
 } 
}

Il y a un problème de compatibilité. IE8 et les versions inférieures ne prennent pas en charge la méthode getElementsByClassName(). J'ai trouvé une solution en ligne

if(!document.getElementsByClassName){ 
 document.getElementsByClassName = function(className, element){ 
  var children = (element || document).getElementsByTagName(&#39;*&#39;); 
  var elements = new Array(); 
  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; 
 }; 
}

J'essaie d'utiliser le. prototype d'Object ou HTMLTableSectionElement Ajoutez cette méthode, telle que

HTMLTableSectionElement.prototype.getElementsByClassName = function(){}

Malheureusement, elle n'est pas implémentée.

Le code modifié est

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; 
 } 
}

En plus du tri, d'autres opérations sont nécessaires, nous créons donc une méthode init() pour gérer de manière centralisée les méthodes reSequence(), dans createTr() La méthode init() est appelée à la fin de la méthode.

Effacer la méthode de ligne vide clearTrs()

Pour supprimer/détruire un objet DOM, la première chose qui vient à l'esprit est la méthode Remove(). Malheureusement, il existe un problème de compatibilité avec le navigateur IE. , utilisez donc Un moyen plus simple consiste à exécuter innerHTML="" sur l'objet dom. Le code est le suivant

function clearTrs() { 
 vTbody.innerHTML = &#39;&#39;; 
}

IE8 signale une erreur, 'Erreur d'exécution inconnue'. J'ai vérifié ce qui suit, car le table.innerHTML d'IE8 est un attribut en lecture seule, bon sang ! Changez à nouveau :

function clearTrs() { 
 while(vTbody.rows.length >0) { 
  vTbody.deleteRow(); 
 } 
}

Méthode de suppression de ligne addBtnDelsListener()

Ensuite, liez la méthode de suppression de la ligne actuelle au bouton SUPPRIMER.

Afin de résoudre le problème de compatibilité, la méthode proposée sur Internet consiste à utiliser respectivement les méthodes addEventListener et attachEvent pour différents navigateurs (IE, non-IE

J'utilise une autre solution). :

obj.onclick = function(){};

Le corps de la méthode de la fonction anonyme a tiré l'expérience et les leçons de la méthode clearTrs() ci-dessus et utilise directement le deleteRow(index ) méthode.

Une chose à noter est que le nombre de lignes obtenues par thisTr.rowIndex est 2 supérieur à la ligne actuelle, car il y a deux lignes supplémentaires dans l'en-tête. Donc le nombre actuel d'index = thisTr.rowIndex-vThead.rows.length

Le code est le suivant :

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 = function() { 
   var vTr = this.parentElement.parentElement; 
   vTbody.deleteRow(vTr.rowIndex-vTbody.parentNode.getElementsByTagName(&#39;thead&#39;)[0].rows.length); 
   reSequence(); 
  }; 
 } 
}

Après avoir effectué l'opération de suppression, réorganisez via la méthode reSequence() .

En même temps, ajoutez la méthode addBtnDelsListener() à la méthode init().

Méthode de copie de ligne addBtnCpsListener()

Regardez à nouveau le bouton COPIER. La méthode d'ajout d'écouteurs d'événements est la même que ci-dessus.

Si innerHTML n'est pas en lecture seule, vous pouvez createElement un élément tr puis newTr.innerHTML=thisTr.innerHTML,

Pour des raisons de compatibilité, certaines modifications doivent être apportées.

En fait, copier peut être considéré comme en créer une nouvelle. La seule différence est que le contenu de la zone de saisie de texte de la nouvelle ligne doit être égal à la ligne copiée.

C'est facile. Je peux d'abord appeler la méthode createTr(), puis définir la valeur de la zone de texte dans le dernier élément lastChild pour qu'elle soit égale à la ligne copiée.

J'ai l'idée, le code est le suivant :

function addBtnCpsListener() { 
 var vBtnCps = vTbody.getElementsByClassName == 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 = function() { 
   createTr(); 
   var vNewTr = vTbody.lastChild; 
   var vTr = this.parentElement.parentElement; 
   vNewTr.getElementsByClassName == null?document.getElementsByClassName(&#39;td-inp-txt&#39;, vNewTr)[0].value = document.getElementsByClassName(&#39;td-inp-txt&#39;, vTr)[0].value:vNewTr.getElementsByClassName(&#39;td-inp-txt&#39;)[0].value = vTr.getElementsByClassName(&#39;td-inp-txt&#39;)[0].value; 
  } 
 } 
}

Optimisation et modifications

Effectuer quelques optimisations et modifications :

var elements = new Array();

modifié en : var elements = [];

Raison : Il est préférable d'utiliser [] pour les tableaux

Changer vBtnDels[i].onclick = function() dans la méthode addBtnDelsListener {

修改为:vBtnDels[i].onclick = delTr;

外部新创建一个函数

function delTr() { 
    var vTr = this.parentElement.parentElement; 
    vTbody.deleteRow(vTr.rowIndex-vTbody.parentNode.getElementsByTagName(&#39;thead&#39;)[0].rows.length); 
    reSequence(); 
   }

原因:Don't make functions within a loop.

同理,将addBtnCpsListener中的vBtnCps[i].onclick = function() {

修改为:vBtnCps[i].onclick = copyTr;

外部新创建一个函数

<pre code_snippet_id="139791" snippet_file_name="blog_20140103_15_6784659" name="code" class="javascript">   function copyTr() { 
    createTr(); 
    var vNewTr = vTbody.lastChild; 
    var vTr = this.parentElement.parentElement; 
    vNewTr.getElementsByClassName === null? 
    document.getElementsByClassName(&#39;td-inp-txt&#39;, vNewTr)[0].value = 
    document.getElementsByClassName(&#39;td-inp-txt&#39;, vTr)[0].value: 
    vNewTr.getElementsByClassName(&#39;td-inp-txt&#39;)[0].value = 
    vTr.getElementsByClassName(&#39;td-inp-txt&#39;)[0].value; 
   }
 

将copyTr()方法中的?:格式修改为if else函数。

修改为:

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; 
  } 
}

原因:?:预期返回值应该是一个变量or函数,而不应该是一个表达式操作。

有一点需要注意:js最佳实现经常看到要使用===替换==。但是本示例中的==null,如果替换成===null会在ie8一下版本中出现问题。

完整代码

至此,一个完全基于原生JavaScript,并且兼容至IE6的table增删完成了。

还是想吐槽一下,如果不兼容IE10以下的版本,可以节省50%的代码。如果使用jQuery,又可以节省50%的代码。对于实用主义的我而言,这一过程备受煎熬。不过还是从中有所收益的(违心。。)

以下为完整代码:

 
 
  
  table 
   
   
  
  
  
This is a table for operations by javascript

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

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


Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn