常見的例子是處理表格的時候。每行行末有個刪除按鈕,點了這個能夠刪除這一行。
- <table>
- <tbody>
- <tr>
- <td>這行原來就有</td>
- <td><buttonclass="del">刪除</button></td>
- </tr>
- <tr>
- <td>這行原來就有</td>
- <td><buttonclass="del">刪除</button></td>
- </tr>
- </tbody>
- </table>
通常,我會這么綁定
1.jQuery(function($){
2. //已有刪除按鈕初始化綁定刪除事件
3. $(".del").click(function() {
4. $(this).parents("tr").remove();
5. });
6.});
對于在domready之前就存在的刪除按鈕,一切都很完美。但如果在domready之后用js動態(tài)添加幾行,那新增的幾行中的這些按鈕都將失去任何作用。
如何解決這個問題?以下提供4種解決方案:
0號解決方案——onclick法
如果不顧結(jié)構(gòu)與行為分離的準(zhǔn)則的話,通常,我會這么做。
注意,此時的deltr這個function必須是全局函數(shù),得放jQuery(function($) {})外面,放里邊就成局部函數(shù)了,html里的onclick就調(diào)用不到了!
- 1.<td><buttononclick="deltr(this)">刪除</button></td>
- 1.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.//刪除行的函數(shù),必須要放domready函數(shù)外面
- 8.function deltr(delbtn){
- 9. $(delbtn).parents("tr").remove();
- 10.};
1號解決方案——重復(fù)綁定法
即,在domready的時候就給已有的元素綁定事件處理函數(shù),
而后當(dāng)新增加的元素的時候再次綁定。
- 1.<td><buttonclass="del">刪除</button></td>
- 1.jQuery(function($){
- 2. //定義刪除按鈕事件綁定
- 3. //寫里邊,防止污染全局命名空間
- 4. function deltr(){
- 5. $(this).parents("tr").remove();
- 6. };
- 7. //已有刪除按鈕初始化綁定刪除事件
- 8. $("#table3 .del").click(deltr);
- 9. //添加行
- 10. $("#add3").click(function(){
- 11. $('<tr><td>新增行</td><td><button class="del">刪除</button></td></tr>')
- 12. //在這里給刪除按鈕再次綁定事件。
- 13. .find(".del").click(deltr).end()
- 14. .appendTo($("#table3>tbody"));
- 15. });
- 16.});
2號解決方案——事件冒泡法
利用事件冒泡的原理,我們給這個按鈕的祖先元素綁定事件處理函數(shù)。
然后通過event.target這個對象來判斷,這個事件是不是我們要找的對象觸發(fā)的。
通常可以利用一些DOM屬性,比如event.target.className、event.target.tagName等之類的來判斷。
- 1.<td><buttonclass="del">刪除</button></td>
- 1.jQuery(function($){
- 2. //第四個表格的刪除按鈕事件綁定
- 3. $("#table4").click(function(e) {
- 4. if (e.target.className=="del"){
- 5. $(e.target).parents("tr").remove();
- 6. };
- 7. });
- 8. //第四個表格的添加按鈕事件綁定
- 9. $("#add4").click(function(){
- 10. $("#table4>tbody").append('<tr><td>新增行</td><td><button class="del">刪除</button></td></tr>')
- 11. });
- 12.});
3號解決方案——復(fù)制事件法
上面幾種方案可以說即便你沒有用到j(luò)Query庫,你也能相對比較容易的實現(xiàn)。但這種方案相對依賴jQuery的程度更高。而且必須要求jQuery 1.2版以上。低版本jQuery需要插件。
上面兩個方案都是對刪除函數(shù)動了很多腦筋,換了多種觸發(fā)、綁定的方式。這個方案不同,可以與平時純靜態(tài)的元素一樣在domready的時候綁定。但在我們添加新行的時候我們改動一下,不再想上面那樣拼接字符串來添加新行了。這回我們嘗試使用復(fù)制DOM元素的方式。并且復(fù)制的時候連同綁定的事件一起復(fù)制,復(fù)制完之后再用find之類的修改內(nèi)部的元素。
同時,就像這個例子,如果你會把所有元素都刪除光,那template這個模板是必須的,如果不會刪光,那就未必需要用template了。為了防止被誤刪,此處我把template設(shè)了隱藏。
我使用了jQuery中特有的clone(true)
- 1..template{display:none;}
- 1.<trclass="template">
- 2. <td>這里是模板</td>
- 3. <td><button class="del">刪除</button></td>
- 4. </tr>
- 5. <tr>
- 6. <td>這行原來就有</td>
- 7. <td><button class="del">刪除</button></td>
- 8. </tr>
- 9. <tr>
- 10. <td>這行原來就有</td>
- 11. <td><button class="del">刪除</button></td>
- 12. </tr>
- 1.jQuery(function($){
- 2. //第五個表格的刪除按鈕事件綁定
- 3. $("#table5 .del").click(function() {
- 4. $(this).parents("tr").remove();
- 5. });
- 6. //第五個表格的添加按鈕事件綁定
- 7. $("#add5").click(function(){
- 8. $("#table5>tbody>tr:eq(0)")
- 9. //連同事件一起復(fù)制
- 10. .clone(true)
- 11. //去除模板標(biāo)記
- 12. .removeClass("template")
- 13. //修改內(nèi)部元素
- 14. .find("td:eq(0)")
- 15. .text("新增行")
- 16. .end()
- 17. //插入表格
- 18. .appendTo($("#table5>tbody"))
- 19. });
- 20.});
總評:
上面4種方案,各有優(yōu)劣。
0號方案,結(jié)構(gòu)與行為完全沒有分離,而且污染全局命名空間。最不推薦。所以我都不把它當(dāng)作一個方案來看。但對于js初學(xué)者,可以用來項目救急。
1號方案,中規(guī)中矩,沒啥好也沒啥不好
2號方案,這種方法充分的發(fā)揮了js事件冒泡的優(yōu)勢。而且效率最高。但同時由于這種方案無視了jQuery強大的選擇器,所以如果涉及的元素屬性要求過多就會比較麻煩了。你會徘徊在眾多if的條件的是非關(guān)系之中。后來我想起來,可以用jQuery中的$(event.target).is(selector)來作為條件。這樣可以極大提升開發(fā)效率,但略微降低執(zhí)行效率。
3號方案,這是我認為最能體現(xiàn)結(jié)構(gòu)與行為分離的思想的一種方案。但缺點也很明顯,對于jQuery依賴性過于高了,要不就自己寫一個復(fù)制連同事件一起復(fù)制的函數(shù),但這也顯然對于初學(xué)者來說異常困難。但從未來的趨勢的角度來看,還是很推薦使用這種方案的。
具體選用哪一個方案,沒有定數(shù)。具體看你的項目以及你js還有結(jié)構(gòu)與行為分離的思想的掌握程度。最適合的才是最好的。
【網(wǎng)站聲明】本站除付費源碼經(jīng)過測試外,其他素材未做測試,不保證完整性,網(wǎng)站上部分源碼僅限學(xué)習(xí)交流,請勿用于商業(yè)用途。如損害你的權(quán)益請聯(lián)系客服QQ:2655101040 給予處理,謝謝支持。