jQuery中事件綁定到bind、live、delegate、on方法的探究


 

1. 給頁面上的某個元素綁定事件,最初采用下面的方式實現:

    $(‘selector’).click(function(){

        //code

});

缺點:

不能同時綁定多個事件,不能綁定動態的元素。

后來接觸到了on、bind、live、delegate,以下是對它們的一些探究。

 

2. bind(type,[data],fn),為每個匹配元素的特定事件綁定事件處理函數,是直接綁定在元素上

說明:

type: 含有一個或多個事件類型的字符串,由空格分隔多個事件。比如"click"或"submit"

    data:作為event.data屬性值傳遞給事件對象的額外數據對象

    fn:綁定到每個匹配元素的事件上面的處理函數

注意:

bind (type,[data],false)
false: 將第三個參數設置為false會使默認的動作失效

jQuery各個版本都支持

使用:

①.同時綁定多個事件類型:

    $('selector').bind('mouseenter mouseleave', function() { 

         //code

});

②.同時綁定多個事件類型/處理程序:

$("button").bind({  
  click:function(){//code},  
  mouseover:function(){//code},    
  mouseout:function(){//code}    
});

③.可以在事件處理之前傳遞一些附加的數據

function handler(event) {  
  alert(event.data.name);  
}  
$("selector").bind("click", {name: "Mary"}, handler)

④.通過返回false來取消默認的行為並阻止事件冒泡

$("form").bind("submit", function() { return false; })

或 $("form").bind("submit", false)

解綁:

unbind():移除bind進行的綁定

優點:

    ①. 這個方法提供了一種在各種瀏覽器之間對事件處理的兼容性解決方案

    ②. .click(), .hover()等事件綁定,都是bind的一種簡化處理方式

缺點:

①. 它會綁定事件到所有的選出來的元素上,當綁定的元素較多時(如:表格的每個單元格),會查找和遍歷每個單元格,導致腳本執行速度明顯變慢;且保存表格的多個單元格元素和相應的處理程序也會占用大量內存。簡言之:綁定元素較多時,效率低下,占用內存。

②. bind只能給調用它的時候已經存在的元素綁定事件,不能給未來新增的元素綁定事件,即不能動態綁定到新增的元素上

③. 當頁面加載完的時候,才可以進行bind()

解決:事件委托/事件代理

補充:

(1)事件代理

實現原理:利用瀏覽器中的事件冒泡和事件源(target || srcElement)

在特定場景中的好處:

    ①. 需要管理的handler(句柄)更少,handler即需要管理的元素

    ②. 占用的內存更少(創建的駐留在內存中的handler少了)

③. DOM元素與代碼更少的綁定

④. DOM變更后(如添加dom節點)無須重新綁定事件處理器

      缺點:

①.並非所有的事件都能冒泡,如load, change, submit, focus, blur(jQuery間接的實現了focus和blur的事件代理)

③.代理元素的handler管理復雜

④.不好模擬用戶觸發事件(jQuery實現了)

(2)事件冒泡

    W3C對DOM2.0定義的標准事件處理流程分為三個階段:事件捕獲階段、事件目標階段、事件冒泡階段

    說明:

    事件捕獲:當某個元素觸發某個事件(如onclick),頂層對象document就會發出一個事件流,隨着DOM樹的節點向目標元素節點流去,直到到達事件真正發生的目標元素。在這個過程中,事件相應的監聽函數是不會被觸發的。

事件目標:當到達目標元素之后,執行目標元素該事件相應的處理函數。如果沒有綁定監聽函數,那就不執行。

事件冒泡:從目標元素開始,往頂層元素傳播。途中如果有節點綁定了相應的事件處理函數,這些函數都會被一次觸發。如果想阻止事件起泡,可以使用e.stopPropagation()(Firefox)或者e.cancelBubble=true(IE)來組織事件的冒泡傳播。

 

3. live(type,[data],fn),給所有匹配的元素附加一個事件處理函數,即使這個元素是以后再添加進來的

說明:

①live()方法是jQuery 1.3新增的,目的是為了解決.bind()方法的缺點,jQuery1.7 之后廢棄,jQuery1.9 刪除

②live()是通過冒泡的方式綁定到元素上的,更適合列表類型,live()方法會把事件綁定到$(document)對象(但這一點從代碼中體現不出來,這也是.live()方法飽受詬病的一個重要原因), 而且只需要給$(document)綁定一次, 然后就能夠處理后續動態加載的元素的事件。在接收到任何事件時,$(document)對象都會檢查事件類型和事件目標,如果是對應的事件且事件目標是對應的目標,那么就執行委托給它的處理程序。

簡單使用:$("table td").live("click",fn)

解綁:$("table td").die("click",fn)

缺點:

①. $()函數會找到當前頁面中的所有td元素並創建jQuery對象,但在確認事件目標時卻不用這個td元素集合,而是使用選擇符表達式與event.target或其祖先元素進行比較,因而生成這個jQuery對象會造成不必要的開銷

②. 默認把事件綁定到$(document)元素,如果DOM嵌套結構很深,事件冒泡通過大量祖先元素會導致性能損失,即存在事件傳播鏈過長的問題

③. 只能放在直接選擇的元素后面,不能在連綴的DOM遍歷方法后面使用,即$("table td").live...可以,但$("table").find("td").live...不行

④. 收集td元素並創建jQuery對象,但實際操作的卻是$(document)對象,令人費解

 

4. $(selector).delegate(childSelector,[type],[data],fn) ,為指定的當前或未來的元素(被選元素的子元素)添加一個或多個事件處理程序,並規定當這些事件發生時運行的函數。

說明:

    delegate()是jQuery 1.4.2新增的,目的是為了解決live()”事件傳播鏈”過長的問題以及不支持鏈式綁定

    delegate()方法的實現依賴於live()

簡單使用:$("table").delegate("td","click",function(){//code})

優點:

使用.delegate()有如下優點(或者說解決了.live()方法的如下問題):

①.直接將目標元素選擇符("td")、事件("click")及處理程序與“受拖方”$("table")綁定,不額外收集元素、事件傳播路徑縮短、語義明確;更精確的小范圍使用事件代理,性能優於.live()

②.支持在連綴的DOM遍歷方法后面調用,即支持$("table").find("#info").delegate...,支持精確控制;

注意:

使用事件委托時,如果注冊到目標元素上的其他事件處理程序使用.stopPropagation()阻止了事件傳播,那么事件委托就會失效。
解綁:undelegate()

 

5. $(selector).on(events,[childSelector],[data],fn) ,在被選當前及未來的元素及子元素上添加一個或多個事件處理程序

說明:

事件綁定與解綁一共有3組(bind、live、delegate),為了避免混亂,自 jQuery 版本 1.7 起,on() 方法是 bind()、live() 和 delegate() 方法的新的替代品。(推薦使用)

解綁: off()  

提示:如需添加只運行一次的事件然后移除,使用 one() 方法


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM