js的事件監聽跟css不一樣,css只要設定好了樣式,不論是原來就有的還是新添加的,都有一樣的表現。而事件監聽不是,你必須給每一個元素單獨綁定事件。
常見的例子是處理表格的時候。每行行末有個刪除按鈕,點了這個能夠刪除這一行。 < table >
< tbody >
< tr >
< td > 這行原來就有 </ td >
< td >< button class = " del " > 刪除 </ button ></ td >
</ tr >
< tr >
< td > 這行原來就有 </ td >
< td >< button class = " del " > 刪除 </ button ></ td >
</ tr >
</ tbody >
</ table >
通常,我會這麼綁定 jQuery(function($){ //已有刪除按鈕初始化綁定刪除事件 $(".del").click(function() { $(this).parents("tr").remove(); }); });
對於在domready之前就存在的刪除按鈕,一切都很完美。但如果在domready之後用js動態添加幾行,那新增的幾行中的這些按鈕都將失去任何作用。
如何解決這個問題。以下提供4種解決方案:
=============================
0號解決方案——onclick法
如果不顧結構與行為分離的準則的話,通常,我會這麼做。
注意,此時的deltr這個function必須是全域函數,得放jQuery(function($) {})外面,放裡邊就成局部函數了,html裡的onclick就調用不到了。 <td><buttononclick="deltr(this)">刪除</button></td> jQuery(function($){ //添加行 $("#add2").click(function(){ $("#table2>tbody").append('<tr><td>新增行</td><td><button nclick="deltr(this)">刪除</button></td></tr>') }); }); //刪除行的函數,必須要放domready函數外面 function deltr(delbtn){ $(delbtn).parents("tr").remove(); };
=============================
1號解決方案——重複綁定法
即,在domready的時候就給已有的元素繫結事件處理函數,
而後當新增加的元素的時候再次綁定。 <td><buttonclass="del">刪除</button></td> jQuery(function($){ //定義刪除按鈕事件綁定 //寫裡邊,防止汙染全域命名空間 function deltr(){ $(this).parents("tr").remove(); }; //已有刪除按鈕初始化綁定刪除事件 $("#table3 .del").click(deltr); //添加行 $("#add3").click(function(){ $('<tr><td>新增行</td><td><button class="del">刪除</button></td></tr>') //在這裡給刪除按鈕再次綁定事件。 .find(".del").click(deltr).end() .appendTo($("#table3>tbody")); }); });
=============================
2號解決方案——事件冒泡法
利用事件冒泡的原理,我們給這個按鈕的祖先元素繫結事件處理函數。
然後通過event.target這個對象來判斷,這個事件是不是我們要找的對象觸發的。
通常可以利用一些DOM屬性,比如event.target.className、event.target.tagName等之類的來判斷。 <td><buttonclass="del">刪除</button></td> jQuery(function($){ //第四個表格的刪除按鈕事件綁定 $("#table4").click(function(e) { if (e.target.className=="del"){ $(e.target).parents("tr").remove(); }; }); //第四個表格的添加按鈕事件綁定 $("#add4").click(function(){ $("#table4>tbody").append('<tr><td>新增行</td><td><button class="del">刪除</button></td></tr>') }); }); 3號解決方案——複製事件法
上面幾種方案可以說即便你沒有用到jQuery庫,你也能相對比較容易的實現。但這種方案相對依賴jQuery的程度更高。而且必須要求jQuery 1.2版以上。低版本jQuery需要外掛程式。
上面兩個方案都是對刪除函數動了很多腦筋,換了多種觸發、綁定的方式。這個方案不同,可以與平時純靜態元素一樣在domready的時候綁定。但在我們添加新行的時候我們改動一下,不再想上面那樣拼接字串來添加新行了。這回我們嘗試使用複製DOM元素的方式。並且複製的時候連同綁定的事件一起複製,複製完之後再用find之類的修改內部的元素。
同時,就像這個例子,如果你會把所有元素都刪除光,那template這個模板是必須的,如果不會刪光,那就未必需要用template了。為了防止被誤刪,此處我把template設了隱藏。
我使用了jQuery中特有的clone(true) .template{display:none;} <trclass="template"> <td>這裡是模板</td> <td><button class="del">刪除</button></td> </tr> <tr> <td>這行原來就有</td> <td><button class="del">刪除</button></td> </tr> <tr> <td>這行原來就有</td> <td><button class="del">刪除</button></td> </tr> jQuery(function($){ //第五個表格的刪除按鈕事件綁定 $("#table5 .del").click(function() { $(this).parents("tr"