This is a table for operations by javascript | ||
---|---|---|
ホームページ > 記事 > ウェブフロントエンド > ピュアネイティブjsでテーブルテーブルの追加・削除を実現
会社のインターンさんからテーブルの追加と削除について質問されましたが、jQueryを使って実装するのはとても簡単でした。また、jQuery を使用せずに js のみを使用して実装する方法についても尋ねました。
このような状況に直面したとき、私の通常のアプローチは「理解できないが、サポートする」です。
私は jQuery をよく使ってきましたが、人々はあまりにも怠け者ですが、この操作を実装するのに依然として js を使用していましたが、問題は IE との互換性にあると思います。 。 。
コードを見つけるだけの場合は、分析プロセスをスキップできます。完全なコードは記事の最後に添付されています。
以下はコーディングプロセスです:
HTML構造コード
いくつかの簡単なスタイルが追加された基本的なテーブル構造、作成、クリア、および1つの予約に対応する3つのボタン。
<!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>
Constructor(擬似コンストラクター)
検討すると、隠しtrを作成し、このtrを元に作成操作を行います。 HTML の全体的な構造を壊さないようにするために、js を通じて tr オブジェクトを生成し、ページに追加することにしました。
ページが読み込まれた後に DOM 操作を実行するには、コードの下部の 36cc49f0c466276486e50c850b7e4956 の前に 3f1c4e4b6b16bbbd69b2ee476dc4f83a を配置します。
テーブル内の tbody に基づいて追加および削除操作を実行するには、最初にこのグローバル変数を宣言します
var vTbody = document.getElementById('main-table').getElementsByTagName('tbody')[0];オブジェクトを作成するには、document.createElement メソッドを使用できます。
オブジェクト指向の方法でプログラムする場合は、最初にコンストラクターを記述します (実際には、これは標準のコンストラクター形式ではありません)。最も内側の要素から始めます。
td にはテキストやボタンなどのフォーム要素が存在する可能性があるため、まず入力コンストラクター関数 myInput(vId, vClass, vType, vValue, vParent) を作成します。{}
ここには互換性の問題、つまり IE が存在します。カーネルは setAttribute(class, value) をサポートしていません。setAttribute(className, value) を使用する必要があるため、互換性の問題を解決するには、FF、Chrome では
setAttribute(class, value) を使用できます。 IE の setAttribute(className, value)
ここでは別のメソッドが使用されています。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 オブジェクトと tr オブジェクトのコンストラクターがあります。コードは次のとおりです。
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()コンストラクターが完了したら、createTr()メソッドを完成させます。 想定されるtr構造はシリアル番号、テキストボックス、操作ボタンです。 関連するオブジェクトを順番に作成します。シリアル番号列は動的に更新する必要があるため、最初にクラス名を設定し、メソッドを通じて並べ替え操作を実行します。
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() 動的ソートメソッド reSequence() を作成します。 Firefox では互換性の問題があるため、innerHTML が使用されます。コードは次のとおりです
function reSequence() { var vObj = vTbody.getElementsByClassName('seq'); for (var i=0, len=vObj.length; i<len; i++) { vObj[i].innerHTML = i+1; } }IE8以下ではgetElementsByClassName()メソッドがサポートされていません
オンラインで解決策を見つけました
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(){}
残念ながら実装されていません。
修正したコードは
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; } }です
ソート以外にも他の操作が必要なので、reSequence()メソッドを一元管理するinit()メソッドを作成し、createTr()の最後でinit()メソッドを呼び出します。 ) 方法。
ClearTrs()
DOM オブジェクトを削除/破棄するには、remove() メソッドが最初に思い浮かびますが、残念ながら、IE ブラウザの互換性の問題があるため、より簡単な方法が採用されています。 innerHTML="" で、コードは次のとおりです
function clearTrs() { vTbody.innerHTML = ''; }
IE8 は「不明な実行エラー」というエラーを報告します。 IE8 の table.innerHTML は読み取り専用属性なので、次のことを確認しました。再度変更します:
function clearTrs() { while(vTbody.rows.length >0) { vTbody.deleteRow(); } }
行の削除メソッド addBtnDelsListener()
次に、現在の行を削除するメソッドを DELETE ボタンにバインドします。
互換性の問題を解決するために、インターネットで提供されている方法は、異なるブラウザー (IE、非 IE) にそれぞれ addEventListener メソッドとattachEvent メソッドを使用することです。
私は別の解決策を使用します:
obj.onclick = function。 (){};
匿名関数のメソッド本体は、上記の clearTrs() メソッドから経験と教訓を学び、deleteRow(index) メソッドを直接使用します。
注意すべき点は、先頭にはあと 2 行あるため、thisTr.rowIndex によって取得される行数は現在の行より 2 多いことです。したがって、現在のインデックス番号 = 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(); }; } }
削除操作を実行した後、reSequence() メソッドを通じて並べ替えます。
また、addBtnDelsListener() メソッドを init() メソッドに追加します。
コピーラインメソッドaddBtnCpsListener()
COPYボタンをもう一度見てみましょう。イベントリスナーを追加する方法は上記と同じです。
innerHTML が読み取り専用でない場合は、createElement と tr 要素を組み合わせて newTr.innerHTML=thisTr.innerHTML にすることができます。
互換性を確保するために、いくつかの変更を加える必要があります。
実際、コピーは新しい行を作成することとみなすことができます。唯一の違いは、新しい行のテキスト入力ボックスの内容がコピーされた行と同じである必要があることです。
それは簡単です。最初に createTr() メソッドを呼び出してから、最後の要素 lastChild のテキスト ボックスの値をコピーされた行と等しくなるように設定します。
アイデアはそこにあり、コードは次のとおりです:
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; } } }
最適化の変更
いくつかの最適化の変更を実行します:
var elements = new Array();
次のように変更します: var elements = [];
Reason : 配列は addBtnDelsListener メソッドで [ ]Better
Place vBtnDels[i].onclick = function() {
を使用します修改为:vBtnDels[i].onclick = delTr;
外部新创建一个函数
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;
外部新创建一个函数
<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; }
将copyTr()方法中的?:格式修改为if else函数。
修改为:
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; } }
原因:?:预期返回值应该是一个变量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中文网!