DOM樹
首先,可視化一個HMTL文檔的DOM樹是很有協助的。一個簡單的HTML頁面看起來就像是這個樣子:事件冒泡(又稱事件傳播)當我們點擊一個連結時,其觸發了連結元素的單擊事件,該事件則引發任何我們已綁定到該元素的單擊事件上的函數的執行。
複製代碼 代碼如下:
$('a').bind('click',function(){alert('that tickles!')})
因此一個單擊操作會觸發alert函數的執行。click事件接著會向樹的根方向傳播,廣播到父元素,然後接著是每個祖先元素,只要是它的某個後代元素上的單擊事件被觸發,事件就會傳給它。在操縱DOM的語境中,document是根節點。現在我們可以較容易地說明.bind()、.live()和.delegate()的不同之處了。
.bind()
複製代碼 代碼如下: $('a').bind('click',function(){alert('That tickles!');})
這是最簡單的Binder 方法了。JQuery掃描文檔找出所有的$(‘a')元素,並把alert函數綁定到每個元素的click事件上。
.live()
複製代碼 代碼如下:$('a').live('click',function(){alert('That tickles!')})
JQuery把alert函數綁定到$(document)元素上,並使用'click'和'a'作為參數。任何時候只要有事件冒泡到document節點上,它就查看該事件是否是一個click事件,以及該事件的目標元素與'a'這一CSS選取器是否匹配,如果都是的話,則執行函數。
live方法還可以被綁定到具體的元素(或“context”)而不是document上,像這樣:
複製代碼 代碼如下:$('a',$('#container')[0]).live('click',function(){alert('That tickles!')})
.delegate()
複製代碼 代碼如下:$('#container').delegate('a','click',function(){alert('That tickles!')})
JQuery掃描文檔尋找$('#container'),並使用click事件和'a'這一CSS選取器作為參數把alert函數綁定到$('#container')上。任何時候只要有事件冒泡到$('#container')上,它就查看該事件是否是click事件,以及該事件的目標元素是否與CSS選取器相匹配。如果兩種檢查的結果都為真的話,它就執行函數。
可以注意到,這一過程與.live()類似,但是其把處理常式綁定到具體的元素而非document這一根上。精明的JS'er們可能會做出這樣的結論,即$('a').live() == $(document).delegate('a'),是這樣嗎?嗯,不,不完全是。
為什麼.delegate()要比.live()好用
基於幾個原因,人們通常更願意選用jQuery的delegate方法而不是live方法。考慮下面的例子:
複製代碼 代碼如下:$('a').live('click', function() { blah() });
或
$(document).delegate('a', 'click', function() { blah() });
後者實際上要快過前者,因為前者首先要掃描整個的文檔尋找所有的$(‘a')元素,把它們存成jQuery對象。儘管live函數僅需要把'a'作為串參數傳遞以用做之後的判斷,但是$()函數並未“知道”被連結的方法將會是.live()。
而另一方面,delegate方法僅需要尋找並儲存$(document)元素。
一種尋求避開這一問題的方法是調用在$(document).ready()之外綁定的live,這樣它就會立即執行。在這種方式下,其會在DOM獲得填充之前運行,因此就不會尋找元素或是建立jQuery對象了。
靈活性和鏈能力live函數也挺令人費解的。想想看,它被鏈到$(‘a')對象集上,但其實際上是在$(document)對象上發生作用。由於這個原因,它能夠試圖以一種嚇死人的方式來把方法鏈到自身上。實際上,我想說的是,以$.live(‘a',…)這一形式作為一種全域性的jQuery方法,live方法會更具意義一些。僅支援CSS選取器最後一點,live方法有一個非常大的缺點,那就是它僅能針對直接的CSS選取器做操作,這使得它變得非常的不靈活。欲瞭解