首頁 >web前端 >js教程 >jquery 新建的元素事件綁定問題解決方案_jquery

jquery 新建的元素事件綁定問題解決方案_jquery

WBOY
WBOY原創
2016-05-16 16:44:441197瀏覽

js的事件監聽跟css不一樣,css只要設定好了樣式,不論是原來就有的還是新加入的,都有一樣的表現。而事件監聽不是,你必須給每個元素單獨綁定事件。

常見的例子是處理表格的時候。每行行末有個刪除按鈕,點了這個能夠刪除這一行。

複製代碼 代碼如下:












這行原來就有 刪除
這行原來就有 刪除


通常,我會這麼綁定
複製代碼 程式碼如下:

jQuery(function($){
//已有刪除按鈕初始化綁定刪除事件
$(".del").click(function () {
$(this).parents("tr").remove();
});
});

對於在domready之前就存在的刪除按鈕,一切都很完美。但如果在domready之後用js動態加入幾行,那麼新增的幾行中的這些按鈕都會失去任何作用。

如何解決這個問題?以下提供4種解決方案:

0號解答-onclick法

如果不顧結構與行為分離的準則的話,通常,我會這麼做。
注意,此時的deltr這個function必須是全域函數,得放jQuery(function($) {})外面,放裡邊就成局部函數了,html裡的onclick就呼叫不到了!
複製程式碼 程式碼如下:

刪除

jQuery(function($){
//新增行
$("#add2").click(function(){
$("#table2>tbody").append(' 新增行 ')
});
});
//刪除行的函數,必須要放domready函數外面
function deltr(delbtn){
$(delbtn). parents("tr").remove();
};

1號解決方案-重複綁定法

即,在domready的時候就給予已有的元素綁定事件處理函數,
而後當新增加的元素的時候再次綁定。
複製程式碼 程式碼如下:

刪除

jQuery(function($){
//定義刪除按鈕事件綁定
//寫裡邊,防止污染全域命名空間
function deltr( ){
$(this).parents("tr").remove();
};
//已有刪除按鈕初始化綁定刪除事件
$("#table3 .del ").click(deltr);
//新增行
$("#add3").click(function(){
$(' 新增行 ')
//在這裡給刪除按鈕再次綁定事件。 del").click(deltr).end()
.appendTo($("#table3>tbody"));
});
});


2號解法-事件冒泡法
利用事件冒泡的原理,我們給這個按鈕的祖先元素綁定事件處理函數。
然後透過event.target這個物件來判斷,這個事件是不是我們要找的物件觸發的。
通常可以利用一些DOM屬性,像是event.target.className、event.target.tagName等之類的來判斷。

複製程式碼 程式碼如下:

刪除

jQuery(function($){
//第四個表格的刪除按鈕事件綁定
$("#table4").click(function(e) {
if (e.target.className=="del"){
$(e.target).parents( "tr").remove();
};
});
//第四個表格的新增按鈕事件綁定
$("#add4").click(function( ){
$("#table4>tbody").append(' 新增行 ')
});
});


3號解法-複製事件法

上面幾種方案可以說即便你沒有用到jQuery函式庫,你也能相對比較容易的實作。但這種方案相對依賴jQuery的程度較高。而且必須要求jQuery 1.2版以上。低版本jQuery需要外掛。
上面兩個方案都是對刪除函數動了很多腦筋,換了多種觸發、綁定的方式。這個方案不同,可以與平時純靜態的元素一樣在domready的時候綁定。但在我們新增一行的時候我們改動一下,不再想上面那樣拼接字串來加入新行了。這回我們嘗試使用複製DOM元素的方式。並且複製的時候連同綁定的事件一起複製,複製完之後再用find之類的修改內部的元素。
同時,就像這個例子,如果你會把所有元素都刪除光,那template這個模板是必須的,如果不會刪光,那就未必需要用template了。為了防止被誤刪,此處我把template設了隱藏。
我使用了jQuery中特有的clone(true)
複製程式碼 程式碼如下:


程式碼如下:
.template{display:none;}


這裡是模板



這行原來就有



這行原來就有



jQuery(function($){
//第五個表格的刪除按鈕事件綁定
$ ("#table5 .del").click(function() {
$(this).parents("tr").remove();
});
//第五表格的新增按鈕事件綁定
$("#add5").click(function(){
$("#table5>tbody>tr:eq(0)")
//連同事件一起複製
.clone(true)
//移除模板標記
.removeClass("template")
//修改內部元素
.find("td:eq(0)")
.text("新增行")
.end()
//插入表格
.appendTo($("#table5>tbody"))
});
});
總評:

上面4種方案,各有優劣。
0號方案,結構與行為完全沒有分離,而且污染全域命名空間。最不推薦。所以我都不把它當作一個方案來看。但對於js初學者,可以用來專案救急。
1號方案,中規中矩,沒啥好也沒啥不好
2號方案,這種方法充分的發揮了js事件冒泡的優勢。而且效率最高。但同時由於這個方案無視了jQuery強大的選擇器,所以如果涉及的元素屬性要求太多就會比較麻煩了。你會徘徊在眾多if的條件的是非關係之中。後來我想起​​來,可以用jQuery中的$(event.target).is(selector)來當條件。這樣可以大幅提升開發效率,但略微降低執行效率。
3號方案,這是我認為最能體現結構與行為分離的想法的一種方案。但缺點也很明顯,對於jQuery依賴性過於高了,要不就自己寫一個複製連同事件一起複製的函數,但這也顯然對於初學者來說異常困難。但從未來的趨勢的角度來看,還是很建議使用這種方案的。

具體選用哪一個方案,沒有定數。具體看你的專案以及你js還有結構與行為分離的想法的掌握程度。最適合的才是最好的。

附加:

把3號方案改造成完美的結構行為分離的樣式。
首先,有template的是模板元素。祂是一切複製的源泉,為了防止被誤刪,所以設為不可見。如果不會刪除光,那麼這個模板元素也是可選的。因為你可以複製任何一個已經存在的用於循環元素。
其次,給每個重複的元素加上一個repeat,方便用於刪除按鈕找到這一級元素。這個是可選的,有時候不需要。
最後是給每一個要修改的元素加上一個類,以便用find找到。例如我這裡就家了content類,新增加的可以修改裡邊的數值。
這樣一個完美的結構與行為分離的案例就完成了。
複製程式碼 程式碼如下:




這裡是模板



這行原來就有



這行原來有





 





jQuery(function($){
//第六個表格的刪除按鈕事件綁定
$("#tbody6 .del" ).click(function() {
$(this).parents(".repeat").remove();
});
//第六個表格的新增按鈕事件綁定
$("#add6").click(function(){
$("#tbody6>.template")
//連同事件一起複製
.clone(true)
/ /移除模板標記
.removeClass("template")
//修改內部元素
.find(".content")
.text("新增行")
.end ()
//插入表格
.appendTo($("#tbody6"))
});
});

同樣,這段js也適用於以下的html結構
複製程式碼 程式碼如下:



  • 這裡是模板
    刪除


  • 這行原來就有



  • 這行原來有


  • ul>


    陳述:
    本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn