我想很多人都會向我一樣曾經 被新元素的事件綁定困惑很久也就是
在頁面加載完成后給元素綁定了事件,但又新增加的元素上卻沒有綁定任何事件。
js的事件監聽跟css不一樣,css只要設定好了樣式,不論是原來就有的還是新添加的,都有一樣的表現。而事件監聽不是,你必須給每一個元素單獨綁定事件。
常見的例子是處理表格的時候。每行行末有個刪除按鈕,點了這個能夠刪除這一行。
<table> <tbody> <tr> <td>這行原來就有</td> <td><buttonclass="del">刪除</button></td> </tr> <tr> <td>這行原來就有</td> <td><buttonclass="del">刪除</button></td> </tr> </tbody> </table>
通常,我會這么綁定:
jQuery(function($){ 2. //已有刪除按鈕初始化綁定刪除事件 3. $(".del").click(function() { 4. $(this).parents("tr").remove(); 5. }); 6.});
對於在domready之前就存在的刪除按鈕,一切都很完美。但如果在domready之后用js動態添加幾行,那新增的幾行中的這些按鈕都將失去任何作用.
如何解決這個問題?以下提供4種解決方案:
=============================
0號解決方案——onclick法
如果不顧結構與行為分離的准則的話,通常,我會這么做。
注意,此時的deltr這個function必須是全局函數,得放jQuery(function($) {})外面,放里邊就成局部函數了,html里的onclick就調用不到了!
<td><buttononclick="deltr(this)">刪除</button></td>
jQuery(function($){ 2. //添加行 3. $("#add2").click(function(){ 4. $("#table2>tbody").append('<tr><td>新增行</td><td><button nclick="deltr(this)">刪除</button></td></tr>') 5. }); 6.}); 7.//刪除行的函數,必須要放domready函數外面 8.function deltr(delbtn){ 9. $(delbtn).parents("tr").remove(); 10.};
=============================
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>') }); });
另外,可以使用live進行綁定,如下:
$('.clickme').live('click', function() { //處理代碼 });
:一般采用0號解決方案