而輔助這些互動功能的語法均需要使用 CSS 及 Javascript
在 Javascript 方面,由於得到 jQuery 的跨瀏覽器語法,在開發 Javascript 新功能時可以不再考慮瀏覽器的問題
可能不少網頁設計者都會遇過類似狀況
輸入文字欄位數量不夠,需要新加入一定數量的輸入文字爛位,但究竟多少才足夠卻不是設計師可以控制
最理想的狀況是由使用者在需要增加資料,增加輸入文字爛位
1 2 3 4 5 6 7 8 9 10 11 12 | <table> <tbody> <tr> <td><input type="text"/></td> <td><input type="button" value="+"/></td> <td><input type="button" value="-"/></td> <td><input type="button" value="▼+"/></td> <td><input type="button" value="▲"/></td> <td><input type="button" value="▼"/></td> </tr> </tbody></table> |
當 - 被按下後,選定的列會被移除
當 ▼+ 被按下後,複製選定的列於下一列
當 ▲ 被按下後,選定的列向上移
當 ▼ 被按下後,選定的列向下移
網上有不少使用 jQuery 的教學達成這種操作
而這裡則是使用 DOM 的方式達成這種操作
先利用 Javascript 的 Prototype 補充原來的 Javascript 的不足之處
Prototype Javascript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | // DOM 的 Node 有 nextSibling 及 previousSibling 屬性// 來獲取 Node 的上一個 Node 及 下一個 Node ,當沒有 Node 時,會得到 null// 但 *Sibling 可能比較難記,可以自行增加 nextNode() 及 previousNode() 功能// (Java 來說會以功能操作比較熟習)Node.prototype.nextNode = function(){ return this.nextSibling;} Node.prototype.previousNode = function(){ return this.previousSibling;} // 但上一個 Node 或下一個 Node 不一定是 Tag// 對於 DOM Tag 與 Tag 之間的空白字元都是 Node 只是 nodeType 的不同// Tag 的 nodeType 為 1Node.prototype.nextTag = function(){ var node = this.nextNode(); while (node != null && node.nodeType != 1){ node = node.nextNode(); } return node;}Node.prototype.previousTag = function(){ var node = this.previousNode(); while (node != null && node.nodeType != 1){ node = node.previousNode(); } return node;} // 獲取第一及最後的 TagNode.prototype.firstTag = function(){ var node = this.firstChild; while (node != null && node.nodeType != 1){ node = node.nextNode(); } return node;}Node.prototype.lastTag = function(){ var node = this.lastChild; while (node != null && node.nodeType != 1){ node = node.previousNode(); } return node;} // DOM 的 Node 只有 insertBefore 功能卻沒有 insertAfter 功能// 可以自行編寫 insertAfter 來補足功能Node.prototype.insertAfter = function(new_node, existing_node){ if (new_node instanceof Node){ existing_node.parentNode.insertBefore(new_node, existing_node.nextNode()); }} // 讓兩個 DOM Node 的位置交換Node.prototype.swap = function(node){ if (node instanceof Node){ var parent = this.parentNode; parent.insertBefore(node.cloneNode(true), this); parent.insertBefore(this.cloneNode(true), node); parent.removeChild(this); parent.removeChild(node); }} // 自編 insertRowBefore 及 insertRowAfter 功能// 將新的 列 新增至 當前列 的 前 或 後HTMLTableRowElement.prototype.insertRowBefore = function(row){ if (row instanceof HTMLTableRowElement){ this.parentNode.insertBefore(row, this); }}HTMLTableRowElement.prototype.insertRowAfter = function(row){ if (row instanceof HTMLTableRowElement){ this.parentNode.insertAfter(row, this); }} |
Javascript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | function add_row(input){ var td = input.parentNode; var tr = td.parentNode; var tx = tr.parentNode; var t_tr = tx.rows[0].cloneNode(true); t_tr.removeAttribute('style'); tr.insertRowAfter(t_tr);}function copy_row_input_value(tr1, tr2){ for (var i = 0; i < tr1.cells.length; i++){ var element = tr1.cells[i].firstChild; if (element instanceof HTMLInputElement){ if (element.type == 'radio' || element.type == 'checkbox'){ tr2.cells[i].firstChild.checked = element.checked; } else { tr2.cells[i].firstChild.value = element.value; } } else if (element instanceof HTMLSelectElement){ tr2.cells[i].firstChild.selectedIndex = element.selectedIndex; } else if (element instanceof HTMLTextAreaElement){ tr2.cells[i].firstChild.innerHTML = element.innerHTML; } }}function copy_row(input){ var td = input.parentNode; var tr = td.parentNode; var tx = tr.parentNode; var t_tr = tx.rows[0].cloneNode(true); t_tr.removeAttribute('style'); tr.insertRowAfter(t_tr); copy_row_input_value(tr, t_tr);}function delete_row(input){ var td = input.parentNode; var tr = td.parentNode; var tx = tr.parentNode; if (tx.rows.length <= 2){ add_row(input); } tx.removeChild(tr);}function move(input, direction){ var td = input.parentNode; var tr = td.parentNode; var tx = tr.parentNode; var t_tr = tr.cloneNode(true); copy_row_input_value(tr, t_tr); if (tr != tx.firstTag().nextTag() && direction == 'up'){ tx.insertBefore(t_tr, tr.previousTag()); tx.removeChild(tr); } else if (tr != tx.lastTag() && direction == 'down'){ tx.insertAfter(t_tr, tr.nextTag()); tx.removeChild(tr); }} function move_up(input){ move(input, 'up');}function move_down(input){ move(input, 'down');} |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <table> <tbody> <tr style="display: none;"> <td><input type="text"/></td> <td><input type="button" value="+" onclick="add_row(this);"/></td> <td><input type="button" value="-" onclick="delete_row(this);"/></td> <td><input type="button" value="▼+" onclick="copy_row(this);"/></td> <td><input type="button" value="▲" onclick="move_down(this);"/></td> <td><input type="button" value="▼" onclick="move_up(this);"/></td> </tr> <tr> <td><input type="text"/></td> <td><input type="button" value="+" onclick="add_row(this);"/></td> <td><input type="button" value="-" onclick="delete_row(this);"/></td> <td><input type="button" value="▼+" onclick="copy_row(this);"/></td> <td><input type="button" value="▲" onclick="move_down(this);"/></td> <td><input type="button" value="▼" onclick="move_up(this);"/></td> </tr> </tbody></table> |
另外由於 input, select, textarea 等 表單元素 不會複製由用戶輸入的 value, checked, selected, innerHTML 等資料
複製列時需要連同 value, checked, selected, innerHTML 等資料一拼複製才能達至複製效果
以下是示範
這種方法的可取之處是不需要使用 id, class 之類的 CSS Selector 達到效果
沒有留言 :
張貼留言