日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

jquery 新建的元素事件綁定問題

 CevenCheng 2012-05-24

jquery 新建的元素事件綁定問題

上一篇 / 下一篇  2008-10-20 21:40:00 / 個人分類:jQuery

demo:http://www./demo/jquery頁面加載完成后元素綁定事件.html

我想很多人都會向我一樣曾經 被新元素的事件綁定困惑很久也就是
在頁面加載完成后給元素綁定了事件,但又新增加的元素上卻沒有綁定任何事件。

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

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

<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法
如果不顧結構與行為分離的準則的話,通常,我會這么做。
注意,此時的deltr這個function必須是全局函數(shù),得放jQuery(function($) {})外面,放里邊就成局部函數(shù)了,html里的onclick就調用不到了!

  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號解決方案——重復綁定法
即,在domready的時候就給已有的元素綁定事件處理函數(shù),
而后當新增加的元素的時候再次綁定。

  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ā)的。
通??梢岳靡恍〥OM屬性,比如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. });

========================= 下 ===================

demo:http://www./demo/jquery頁面加載完成后元素綁定事件.html
2號解決方案——事件冒泡法
利用事件冒泡的原理,我們給這個按鈕的祖先元素綁定事件處理函數(shù)。
然后通過event.target這個對象來判斷,這個事件是不是我們要找的對象觸發(fā)的。
通??梢岳靡恍〥OM屬性,比如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號解決方案——復制事件法
上面幾種方案可以說即便你沒有用到jQuery庫,你也能相對比較容易的實現(xiàn)。但這種方案相對依賴jQuery的程度更高。而且必須要求jQuery 1.2版以上。低版本jQuery需要插件。
上面兩個方案都是對刪除函數(shù)動了很多腦筋,換了多種觸發(fā)、綁定的方式。這個方案不同,可以與平時純靜態(tài)的元素一樣在domready的時候綁定。但在我們添加新行的時候我們改動一下,不再想上面那樣拼接字符串來添加新行了。這回我們嘗試使用復制DOM元素的方式。并且復制的時候連同綁定的事件一起復制,復制完之后再用find之類的修改內部的元素。
同時,就像這個例子,如果你會把所有元素都刪除光,那template這個模板是必須的,如果不會刪光,那就未必需要用template了。為了防止被誤刪,此處我把template設了隱藏。
我使用了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.            //連同事件一起復制
  10.             .clone(true)
  11.            //去除模板標記
  12.             .removeClass("template")
  13.            //修改內部元素
  14.             .find("td:eq(0)")
  15.                 .text("新增行")
  16.                 .end()
  17.            //插入表格
  18.             .appendTo($("#table5>tbody"))
  19.    });
  20. });

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

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

=============================
附加:
把3號方案改造成完美的結構行為分離的樣式。
首先,帶有template的是模板元素。他是一切復制的源泉,為了防止被誤刪,所以設為不可見。如果不會刪除光,那么這個模板元素也是可選的。因為你可以復制任何一個已經存在的用于循環(huán)元素。
其次,給每個重復的元素加上一個repeat,方便用于刪除按鈕找到這一級元素。這個是可選的,有時候并不需要。
最后是給每一個要修改的元素加上一個類,便于用find找到。比如我這里就家了content類,新增加的可以修改里邊的值。
這樣一個完美的結構與行為分離的案例就完成了。

  1. <tableid="table6">
  2.    <tbody id="tbody6">
  3.        <tr class="template repeat">
  4.            <td class="content">這里是模板</td>
  5.            <td><button class="del">刪除</button></td>
  6.        </tr>
  7.        <tr class="repeat">
  8.            <td class="content">這行原來就有</td>
  9.            <td><button class="del">刪除</button></td>
  10.        </tr>
  11.        <tr class="repeat">
  12.            <td class="content">這行原來就有</td>
  13.            <td><button class="del">刪除</button></td>
  14.        </tr>
  15.    </tbody>
  16.    <tfoot>
  17.        <tr>
  18.            <td> </td>
  19.            <td><button id="add6">添加</button></td>
  20.        </tr>
  21.    </tfoot>
  22. </table>
  1. jQuery(function($){
  2.    //第六個表格的刪除按鈕事件綁定
  3.     $("#tbody6 .del").click(function() {
  4.         $(this).parents(".repeat").remove();
  5.    });
  6.    //第六個表格的添加按鈕事件綁定
  7.     $("#add6").click(function(){
  8.         $("#tbody6>.template")
  9.            //連同事件一起復制
  10.             .clone(true)
  11.            //去除模板標記
  12.             .removeClass("template")
  13.            //修改內部元素
  14.             .find(".content")
  15.                 .text("新增行")
  16.                 .end()
  17.            //插入表格
  18.             .appendTo($("#tbody6"))
  19.    });
  20. });

同樣,這段js也適用于如下的html結構

  1. <ulid="tbody6">
  2.    <li class="template repeat">
  3.        <span class="content">這里是模板</span>
  4.        <span><button class="del">刪除</button></span>
  5.    </li>
  6.    <li class="repeat">
  7.        <span class="content">這行原來就有</span>
  8.        <span><button class="del">刪除</button></span>
  9.    </li>
  10.    <li class="repeat">
  11.        <span class="content">這行原來就有</span>
  12.        <span><button class="del">刪除</button></span>
  13.    </li>
  14. </ul>

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多