欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

純?cè)鷍s實(shí)現(xiàn)table表格的增刪

 更新時(shí)間:2017年01月05日 15:19:48   作者:wangyuheng77  
本文主要介紹了純?cè)鷍avascript實(shí)現(xiàn)table表格的增刪的方法,文章底部提供了完整的代碼。需要的朋友一起來(lái)看下吧

公司實(shí)習(xí)生問(wèn)我table的增刪操作,用jQuery很簡(jiǎn)單的實(shí)現(xiàn)了。又問(wèn)我不使用jQuery,只使用js如何實(shí)現(xiàn)。

面對(duì)這種情況,我的一貫做法是‘不理解,但是支持'。

jQuery用的多了,人也懶了,但還是用js實(shí)現(xiàn)了這一操作,覺得難點(diǎn)在于IE兼容。。。

只是想找代碼看看的可以跳過(guò)分析過(guò)程,文章底部附有完整代碼。

以下是coding過(guò)程:

HTML結(jié)構(gòu)代碼

一個(gè)基本的table結(jié)構(gòu),增加了一些簡(jiǎn)單的樣式,三個(gè)按鈕分別對(duì)應(yīng)創(chuàng)建、清空,和一個(gè)預(yù)留。

<!DOCTYPE HTML> 
<html> 
 <head> 
 <title>table</title> 
 <meta charset='utf-8' /> 
 <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> 

構(gòu)造函數(shù)(偽構(gòu)造函數(shù))

考慮過(guò),創(chuàng)建一個(gè)隱藏的tr,基于此tr執(zhí)行創(chuàng)建操作。為了不破壞HTML整體結(jié)構(gòu),決定通過(guò)js生成tr對(duì)象并append到頁(yè)面中。

為了在頁(yè)面加載完成后,再執(zhí)行dom操作,所以將<script>放在代碼下端</body>之前。

基于table中的tbody進(jìn)行增刪操作,可以先聲明此全局變量

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

創(chuàng)建對(duì)象,可以使用document.createElement方法。

以面向?qū)ο蟮姆绞竭M(jìn)行編程,先寫構(gòu)造函數(shù)(其實(shí)并不是標(biāo)準(zhǔn)的構(gòu)造函數(shù)格式),從最內(nèi)部的元素開始。

td中可能會(huì)有text和button等表單元素,所以先創(chuàng)建一個(gè) input 的構(gòu)造函數(shù)function myInput(vId, vClass, vType, vValue, vParent){}

這里有一個(gè)兼容性問(wèn)題,就是IE內(nèi)核不支持setAttribute(class, value),需要使用setAttribute(className, value),所以為了解決兼容問(wèn)題,可以通過(guò)

setAttribute(class, value) for FF、Chrome..

setAttribute(className, value) for IE

這里采用的是另一種方式 .className,代碼如下:

function myInput(vId, vClass, vType, vValue, vParent) { 
 var vInput = document.createElement('input'); 
 if(vId) { 
 vInput.setAttribute('id', vId); 
 } 
 vInput.setAttribute('type', vType); 
 vInput.setAttribute('value', vValue); 
 vInput.className = vClass; 
 if(vParent) { 
 vParent.appendChild(vInput); 
 } 
} 

然后是td對(duì)象和tr對(duì)象的構(gòu)造函數(shù),大同小異,代碼如下

function myTd(vId, vClass, vChild, vParent) { 
 var vTd = document.createElement('td'); 
 if(vId){ 
 vTd.setAttribute('id', 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('tr'); 
 if(vId){ 
 vTr.setAttribute('id', vId); 
 } 
 vTr.className = vClass; 
 if(vChild) { 
 vTr.appendChild(vChild); 
 } 
 if(vParent) { 
 vParent.appendChild(vTr); 
 } 
 return vTr; 
} 

新建行方法createTr()

構(gòu)造函數(shù)完成之后,完善createTr()方法。

預(yù)想的tr結(jié)構(gòu)為 序號(hào),文本框,操作按鈕。

依次創(chuàng)建相關(guān)對(duì)象。序號(hào)列需要?jiǎng)討B(tài)刷新,所以先設(shè)定class名稱,通過(guò)方法執(zhí)行排序操作。

function createTr() { 
 var vTr = new myTr(null, null, null, vTbody); 
 //序列td 
 var vTdSeq = new myTd(null, 'seq', null, vTr); 
 //文本框td 
 var vTdText = new myTd(null, null, null, vTr); 
 var vInputText = new myInput(null, 'td-inp-txt', 'text', '', vTdText); 
 //操作按鈕td 
 var vTdBtn = new myTd(null, null, null, vTr); 
 var vInputBtnCp = new myInput(null, 'td-inp-btn-cp', 'button', 'COPY', vTdBtn); 
 var vInputBtnDel = new myInput(null, 'td-inp-btn-del', 'button', 'DELETE', vTdBtn); 
} 

排序方法reSequence()

創(chuàng)建一個(gè)動(dòng)態(tài)排序方法reSequence() ,有一個(gè)兼容性問(wèn)題 innerText在火狐下無(wú)效果,所以使用innerHTML。代碼如下

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

有一個(gè)兼容性問(wèn)題,IE8及以下不支持getElementsByClassName()方法,網(wǎng)上找到了解決方案

if(!document.getElementsByClassName){ 
 document.getElementsByClassName = function(className, element){ 
 var children = (element || document).getElementsByTagName('*'); 
 var elements = new Array(); 
 for (var i=0; i<children.length; i++){ 
 var child = children[i]; 
 var classNames = child.className.split(' '); 
 for (var j=0; j<classNames.length; j++){ 
 if (classNames[j] == className){ 
  elements.push(child); 
  break; 
 } 
 } 
 } 
 return elements; 
 }; 
} 

試圖在Object或者是HTMLTableSectionElement的原型上增加此方法,如

HTMLTableSectionElement.prototype.getElementsByClassName = function(){} 

可惜沒有實(shí)現(xiàn)。

修改后的代碼為

function reSequence() { 
 var vObj = vTbody.getElementsByClassName == null?document.getElementsByClassName('seq', vTbody):vTbody.getElementsByClassName('seq'); 
 for (var i=0, len=vObj.length; i<len; i++) { 
 vObj[i].innerHTML = i+1; 
 } 
} 

除了排序外,還需其他操作,所以我們創(chuàng)建一個(gè)init()方法,集中管理reSequence()這些方法,在createTr()方法的結(jié)尾調(diào)用init()方法。

清空行方法clearTrs()

移除/銷毀某個(gè)dom對(duì)象,首先想到的是remove()方法,不幸的是,存在IE瀏覽器兼容問(wèn)題,因此,采用了一個(gè)更簡(jiǎn)便的方式,對(duì)dom對(duì)象執(zhí)行innerHTML="",代碼如下

function clearTrs() { 
 vTbody.innerHTML = ''; 
} 

IE8報(bào)錯(cuò),'未知的運(yùn)行錯(cuò)誤'。查了以下,因?yàn)閕e8的table.innerHTML是只讀屬性,妹的!再改:

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

刪除行方法addBtnDelsListener()

接下來(lái),給DELETE按鈕綁定刪除當(dāng)前行的方法。

為了解決兼容性問(wèn)題,網(wǎng)上給出的方法是針對(duì)不同瀏覽器(IE、非IE)分別使用addEventListener、attachEvent方法,

我采用的是另一種解決方案:

obj.onclick = function(){};

匿名函數(shù)的方法體,吸取了上面clearTrs()方法的經(jīng)驗(yàn)教訓(xùn),直接采用deleteRow(index)方法。

有一點(diǎn)需要注意thisTr.rowIndex獲取的行數(shù),比當(dāng)前行要大2,因?yàn)閠head中還有兩行。所以當(dāng)前的索引數(shù)=thisTr.rowIndex-vThead.rows.length

代碼如下:

function addBtnDelsListener() { 
 var vBtnDels = vTbody.getElementsByClassName == null?document.getElementsByClassName('td-inp-btn-del', vTbody):vTbody.getElementsByClassName('td-inp-btn-del'); 
 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('thead')[0].rows.length); 
 reSequence(); 
 }; 
 } 
} 

執(zhí)行完刪除操作后,通過(guò)reSequence()方法重新排序。

同時(shí)將addBtnDelsListener()方法加入到init()方法中。

復(fù)制行方法addBtnCpsListener()

再來(lái)看一下COPY按鈕,添加事件監(jiān)聽的方式同上。

如果innerHTML不是只讀的話,可以createElement一個(gè)tr元素 然后newTr.innerHTML=thisTr.innerHTML,

為了兼容性,必須做些改變。

其實(shí)可以將復(fù)制看做是新建,唯一的不同在于新建行的文本輸入框的內(nèi)容要等同于被復(fù)制行。

這就簡(jiǎn)單了。我可以先調(diào)用createTr()方法,再將最后一個(gè)元素lastChild中的文本框的value等于被復(fù)制行。

思路有了,代碼如下:

function addBtnCpsListener() { 
 var vBtnCps = vTbody.getElementsByClassName == null?document.getElementsByClassName('td-inp-btn-cp', vTbody):vTbody.getElementsByClassName('td-inp-btn-cp'); 
 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('td-inp-txt', vNewTr)[0].value = document.getElementsByClassName('td-inp-txt', vTr)[0].value:vNewTr.getElementsByClassName('td-inp-txt')[0].value = vTr.getElementsByClassName('td-inp-txt')[0].value; 
 } 
 } 
} 

優(yōu)化修改

進(jìn)行一些優(yōu)化修改工作:

var elements = new Array();

修改為:var elements = [];

原因:數(shù)組用[]更好

addBtnDelsListener方法中的vBtnDels[i].onclick = function() {

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

外部新創(chuàng)建一個(gè)函數(shù)

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

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

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

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

外部新創(chuàng)建一個(gè)函數(shù)

<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('td-inp-txt', vNewTr)[0].value = 
 document.getElementsByClassName('td-inp-txt', vTr)[0].value: 
 vNewTr.getElementsByClassName('td-inp-txt')[0].value = 
 vTr.getElementsByClassName('td-inp-txt')[0].value; 
 }</pre> 
<pre></pre> 
<pre></pre> 

copyTr()方法中的?:格式修改為if else函數(shù)。

修改為:

function copyTr() { 
 createTr(); 
 var vNewTr = vTbody.lastChild; 
 var vTr = this.parentElement.parentElement; 
 if(vNewTr.getElementsByClassName) { 
 vNewTr.getElementsByClassName('td-inp-txt')[0].value = 
 vTr.getElementsByClassName('td-inp-txt')[0].value; 
 } else { 
 document.getElementsByClassName('td-inp-txt', vNewTr)[0].value = 
 document.getElementsByClassName('td-inp-txt', vTr)[0].value; 
 } 
} 

原因:?:預(yù)期返回值應(yīng)該是一個(gè)變量or函數(shù),而不應(yīng)該是一個(gè)表達(dá)式操作。

有一點(diǎn)需要注意:js最佳實(shí)現(xiàn)經(jīng)??吹揭褂?==替換==。但是本示例中的==null,如果替換成===null會(huì)在ie8一下版本中出現(xiàn)問(wèn)題。

完整代碼

至此,一個(gè)完全基于原生JavaScript,并且兼容至IE6的table增刪完成了。

還是想吐槽一下,如果不兼容IE10以下的版本,可以節(jié)省50%的代碼。如果使用jQuery,又可以節(jié)省50%的代碼。對(duì)于實(shí)用主義的我而言,這一過(guò)程備受煎熬。不過(guò)還是從中有所收益的(違心。。)

以下為完整代碼:

<!DOCTYPE HTML> 
<html> 
 <head> 
 <title>table</title> 
 <meta charset='utf-8' /> 
 <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('*'); 
  var elements = []; 
  for (var i=0; i<children.length; i++){ 
  var child = children[i]; 
  var classNames = child.className.split(' '); 
  for (var j=0; j<classNames.length; j++){ 
  if (classNames[j] == className){ 
  elements.push(child); 
  break; 
  } 
  } 
  } 
  return elements; 
 }; 
 } 
 var vTbody = document.getElementById('main-table').getElementsByTagName('tbody')[0]; 
 function myInput(vId, vClass, vType, vValue, vParent) { 
 var vInput = document.createElement('input'); 
 if(vId) { 
  vInput.setAttribute('id', vId); 
 } 
 vInput.setAttribute('type', vType); 
 vInput.setAttribute('value', vValue); 
 vInput.className = vClass; 
 if(vParent) { 
  vParent.appendChild(vInput); 
 } 
 return vInput; 
 } 
 function myTd(vId, vClass, vChild, vParent) { 
 var vTd = document.createElement('td'); 
 if(vId){ 
  vTd.setAttribute('id', 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('tr'); 
 if(vId){ 
  vTr.setAttribute('id', 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, 'seq', null, vTr); 
 //文本框td 
 var vTdText = new myTd(null, null, null, vTr); 
 var vInputText = new myInput(null, 'td-inp-txt', 'text', '', vTdText); 
 //操作按鈕td 
 var vTdBtn = new myTd(null, null, null, vTr); 
 var vInputBtnCp = new myInput(null, 'td-inp-btn-cp', 'button', 'COPY', vTdBtn); 
 var vInputBtnDel = new myInput(null, 'td-inp-btn-del', 'button', 'DELETE', 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('seq', vTbody): 
vTbody.getElementsByClassName('seq'); 
 for (var i=0, len=vObj.length; i<len; i++) { 
  vObj[i].innerHTML = i+1; 
 } 
 } 
 function addBtnDelsListener() { 
 var vBtnDels = vTbody.getElementsByClassName == null? 
document.getElementsByClassName('td-inp-btn-del', vTbody): 
vTbody.getElementsByClassName('td-inp-btn-del'); 
 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('thead')[0].rows.length); 
 reSequence(); 
 } 
 function addBtnCpsListener() { 
 var vBtnCps = vTbody.getElementsByClassNamenull == null? 
document.getElementsByClassName('td-inp-btn-cp', vTbody): 
vTbody.getElementsByClassName('td-inp-btn-cp'); 
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('td-inp-txt')[0].value = 
  vTr.getElementsByClassName('td-inp-txt')[0].value; 
 } else { 
  document.getElementsByClassName('td-inp-txt', vNewTr)[0].value = 
  document.getElementsByClassName('td-inp-txt', vTr)[0].value; 
 } 
 } 
 </script> 
 </body> 
</html> 

以上就是本文的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,同時(shí)也希望多多支持腳本之家!

相關(guān)文章

最新評(píng)論