欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

jQuery中的.bind()、.live()和.delegate()之間區(qū)別分析

 更新時(shí)間:2011年06月08日 01:34:30   作者:  
jQuery中的.bind()、.live()和.delegate()之間區(qū)別分析,學(xué)習(xí)jquery的朋友可以參考下。
DOM樹(shù)

首先,可視化一個(gè)HMTL文檔的DOM樹(shù)是很有幫助的。一個(gè)簡(jiǎn)單的HTML頁(yè)面看起來(lái)就像是這個(gè)樣子:
事件冒泡(又稱(chēng)事件傳播)
當(dāng)我們點(diǎn)擊一個(gè)鏈接時(shí),其觸發(fā)了鏈接元素的單擊事件,該事件則引發(fā)任何我們已綁定到該元素的單擊事件上的函數(shù)的執(zhí)行。
復(fù)制代碼 代碼如下:

$('a').bind('click',function(){alert('that tickles!')})

因此一個(gè)單擊操作會(huì)觸發(fā)alert函數(shù)的執(zhí)行。
click事件接著會(huì)向樹(shù)的根方向傳播,廣播到父元素,然后接著是每個(gè)祖先元素,只要是它的某個(gè)后代元素上的單擊事件被觸發(fā),事件就會(huì)傳給它。
在操縱DOM的語(yǔ)境中,document是根節(jié)點(diǎn)。
現(xiàn)在我們可以較容易地說(shuō)明.bind()、.live()和.delegate()的不同之處了。
.bind()
復(fù)制代碼 代碼如下:
$('a').bind('click',function(){alert('That tickles!');})

這是最簡(jiǎn)單的綁定方法了。JQuery掃描文檔找出所有的$(‘a(chǎn)')元素,并把a(bǔ)lert函數(shù)綁定到每個(gè)元素的click事件上。
.live()
復(fù)制代碼 代碼如下:
$('a').live('click',function(){alert('That tickles!')})

JQuery把a(bǔ)lert函數(shù)綁定到$(document)元素上,并使用'click'和'a'作為參數(shù)。任何時(shí)候只要有事件冒泡到document節(jié)點(diǎn)上,它就查看該事件是否是一個(gè)click事件,以及該事件的目標(biāo)元素與'a'這一CSS選擇器是否匹配,如果都是的話(huà),則執(zhí)行函數(shù)。
live方法還可以被綁定到具體的元素(或“context”)而不是document上,像這樣:
復(fù)制代碼 代碼如下:
$('a',$('#container')[0]).live('click',function(){alert('That tickles!')})

.delegate()
復(fù)制代碼 代碼如下:
$('#container').delegate('a','click',function(){alert('That tickles!')})


JQuery掃描文檔查找$('#container'),并使用click事件和'a'這一CSS選擇器作為參數(shù)把a(bǔ)lert函數(shù)綁定到$('#container')上。任何時(shí)候只要有事件冒泡到$('#container')上,它就查看該事件是否是click事件,以及該事件的目標(biāo)元素是否與CSS選擇器相匹配。如果兩種檢查的結(jié)果都為真的話(huà),它就執(zhí)行函數(shù)。
可以注意到,這一過(guò)程與.live()類(lèi)似,但是其把處理程序綁定到具體的元素而非document這一根上。精明的JS'er們可能會(huì)做出這樣的結(jié)論,即$('a').live() == $(document).delegate('a'),是這樣嗎?嗯,不,不完全是。
為什么.delegate()要比.live()好用
基于幾個(gè)原因,人們通常更愿意選用jQuery的delegate方法而不是live方法??紤]下面的例子:
復(fù)制代碼 代碼如下:
$('a').live('click', function() { blah() });


$(document).delegate('a', 'click', function() { blah() });
后者實(shí)際上要快過(guò)前者,因?yàn)榍罢呤紫纫獟呙枵麄€(gè)的文檔查找所有的$(‘a(chǎn)')元素,把它們存成jQuery對(duì)象。盡管live函數(shù)僅需要把'a'作為串參數(shù)傳遞以用做之后的判斷,但是$()函數(shù)并未“知道”被鏈接的方法將會(huì)是.live()。

而另一方面,delegate方法僅需要查找并存儲(chǔ)$(document)元素。
一種尋求避開(kāi)這一問(wèn)題的方法是調(diào)用在$(document).ready()之外綁定的live,這樣它就會(huì)立即執(zhí)行。在這種方式下,其會(huì)在DOM獲得填充之前運(yùn)行,因此就不會(huì)查找元素或是創(chuàng)建jQuery對(duì)象了。
靈活性和鏈能力
live函數(shù)也挺令人費(fèi)解的。想想看,它被鏈到$(‘a(chǎn)')對(duì)象集上,但其實(shí)際上是在$(document)對(duì)象上發(fā)生作用。由于這個(gè)原因,它能夠試圖以一種嚇?biāo)廊说姆绞絹?lái)把方法鏈到自身上。實(shí)際上,我想說(shuō)的是,以$.live(‘a(chǎn)',…)這一形式作為一種全局性的jQuery方法,live方法會(huì)更具意義一些。
僅支持CSS選擇器
最后一點(diǎn),live方法有一個(gè)非常大的缺點(diǎn),那就是它僅能針對(duì)直接的CSS選擇器做操作,這使得它變得非常的不靈活。
欲了解更多關(guān)于CSS選擇器的缺點(diǎn),請(qǐng)參閱Exploring jQuery .live() and .die()一文。
更新:感謝Hacker News上的pedalpete和后面評(píng)論中的Ellsass提醒我加入接下來(lái)的這一節(jié)內(nèi)容。
為什么選擇.live()或.delegate()而不是.bind()
畢竟,bind看起來(lái)似乎更加的明確和直接,難道不是嗎?嗯,有兩個(gè)原因讓我們更愿意選擇delegate或live而不是bind:
1. 為了把處理程序附加到可能還未存在于DOM中的DOM元素之上。因?yàn)閎ind是直接把處理程序綁定到各個(gè)元素上,它不能把處理程序綁定到還未存在于頁(yè)面中的元素之上。
2. 如果你運(yùn)行了$('a').bind(…),而后新的鏈接經(jīng)由AJAX加入到了頁(yè)面中,則你的bind處理程序?qū)τ谶@些新加入的鏈接來(lái)說(shuō)是無(wú)效的。而另一方面live和delegate則是被綁定到另一個(gè)祖先節(jié)點(diǎn)上,因此其對(duì)于任何目前或是將來(lái)存在于該祖先元素之內(nèi)的元素都是有效的。
3. 或者為了把處理程序附加到單個(gè)元素上或是一小組元素之上,監(jiān)聽(tīng)后代元素上的事件而不是循環(huán)遍歷并把同一個(gè)函數(shù)逐個(gè)附加到DOM中的100個(gè)元素上。把處理程序附加到一個(gè)(或是一小組)祖先元素上而不是直接把處理程序附加到頁(yè)面中的所有元素上,這種做法帶來(lái)了性能上的好處。
停止傳播
最后一個(gè)我想做的提醒與事件傳播有關(guān)。通常情況下,我們可以通過(guò)使用這樣的事件方法來(lái)終止處理函數(shù)的執(zhí)行:
復(fù)制代碼 代碼如下:

$('a').bind('click',function(e){
e.preventDefault()
e.stopPropagation()}
)

不過(guò),當(dāng)我們使用live或是delegate方法的時(shí)候,處理函數(shù)實(shí)際上并沒(méi)有在運(yùn)行,需要等到事件冒泡到處理程序?qū)嶋H綁定的元素上時(shí)函數(shù)才會(huì)運(yùn)行。而到此時(shí)為止,我們的其他的來(lái)自.bind()的處理函數(shù)早已運(yùn)行了。

相關(guān)文章

最新評(píng)論