jQuery三種事件綁定方式.bind(),.live(),.delegate()

.bind().live() .delegate()之間的區別並不明顯。可是理解它們的不一樣之處有助於寫出更簡潔的代碼,並防止咱們的交互程序中出現沒有預料到的bugcss

基礎jquery

DOMajax

首先,圖形化的HTML文檔能幫助咱們更好的理解。一個簡單的HTML頁面看起來應該像這樣api

 

事件冒泡(也稱做事件傳遞)(Event bubbling aka event propagation函數

點擊一個連接,觸發綁定在連接元素上的 click 事件,進而觸發綁定到這個元素的click事件的函數。性能

1spa

$('a').bind('click', function() { alert("That tickles!") });對象

  

因此一次點擊會觸發一個alert

而後,這個 click 事件會從DOM樹向上傳遞,傳播到父元素,而後傳遞給每個祖先元素。blog

 

DOM樹中, document 是根節點。
如今咱們能容易的解釋.bind().live() .delegate()之間的差異了事件

.bind()

1

$('a').bind('click', function() { alert("That tickles!") });

  

這是最直接的綁定方法。jQuery 掃描文檔找到全部 $(‘a’) 元素,而後給每個找到的元素的 click 事件綁定處理函數。

.live()

1

$('a').live('click', function() { alert("That tickles!") });

  

  jQuery綁定處理函數到 $(document) 元素,並把 ‘click’ 和 ‘a’ 做爲函數的參數。有事件冒泡到document節點的時候,檢查這個事件是否是 click 事件,target element能不能匹配 ‘a’ css選擇器,若是兩個條件都是true,處理函數執行。

live方法也能夠綁定到指定的元素(或者說上下文(context)」)而不用綁定到document,好比:

1

$('a', $('#container')[0]).live(...);

  

.delegate()

1

$('#container').delegate('a', 'click', function() { alert("That tickles!") });

  

jQuery掃描文檔找到 $(‘#container’),綁定處理函數到他的 click 事件,’a’ css選擇器做爲函數的參數。當有事件冒泡到 $(‘#container’),檢查事件是否是 click,並檢查target element是否是匹配css選擇器,若是二者都符合,執行函數。

注意此次和 .live() 方法很類似,除了把事件綁定到特定元素與跟元素的區別。精明的JS’er 或許會總結成 $(‘a’).live() == $(document).delegate(‘a’),真的是這樣嗎? 不,不全是。

爲何 .delegate() 比 .live() 

jQuery 的 delegate方法比 live 方法更應該成爲首選有一個緣由。考慮如下的場景:

1

2

3

$('a').live('click', function() { blah() });

// or

$(document).delegate('a', 'click', function() { blah() });

  

速度

上面第二個執行比第一個快,由於第一個會遍歷整個文檔查找 $(‘a’) 元素,並保存爲jQuery對象,可是live方法只須要傳一個字符串參數’a'而已,$() 方法並不知道咱們會用鏈式表達式在後面用上.live()

delegate 方法就只須要找到並存貯 $(document)元素就夠了。

有一種hack是在 $(document).ready()以外調用live方法,這樣就會當即執行。這時候DOM尚未填充,也就不會查找元素或建立jQuery對象。

靈活性和鏈式語法

這方面live方法依然使人費解。想一下,它鏈在$(‘a’)對象,但其實是在$(document)對象起做用。由於這個緣由,在鏈式表達式中使用live讓人很不安,我以爲live方法變成一個全局的jQuery方法 $.live(‘a’,…) 會更有意義。

只支持css選擇器

最後,live方法有一個最大的缺點,只能用css選擇器,用起來很不方便。

有關css選擇器的缺點,參看 Exploring jQuery .live() and .die()

原做者更新

爲何使用 .live() 或 .delegate() 而不用 .bind()

最後,bind 方法看起來更清晰,更直接,是嗎?可是這裏有兩個緣由咱們推薦 delegate 或 live:

  • 綁定事件處理函數到還不存在DOM中的元素。 bind 方法直接綁定函數到每一個單獨的元素,不能綁定到尚未添加到頁面裏的元素,若是你寫了$(‘a’).bind(…),而後用ajax給頁面增長了新的連接,新添加的連接不會綁定事件。live 或 delegate 或者其它綁定到祖先元素的事件,讓如今有的元素,或者之後增的元素均可以使用。
  • 綁定處理函數到一個元素或者少數幾個元素,監聽後代元素,而不是綁定100個相同的處理函數到單獨的元素。這樣更有性能優點。

阻止冒泡

最後注意一下事件冒泡。一般咱們能用這樣的方法阻止其餘處理函數:

1

2

3

4

5

$('a').bind('click', function(){   

    e.preventDefault();    

    //or    

    e.stopPropagation();

})

  

可是在這裏,用 live 或 delegate 方法綁定的事件會一直傳遞到事件真正綁定的地方纔會執行。這時其餘的函數已經執行過了。

相關文章
相關標籤/搜索