據我所知,.live()
和.on()
,你包含的兩個例子並不是同樣的東西。
你的第一個:
$('#some-button').on('click', function() {
//do something when #some-button is clicked
});
沒有live
行爲。它找到#some-button
對象並直接在其上安裝事件處理程序。這是非常有效的,但沒有.live()
行爲。如果此時#some-button
對象不存在,則不會安裝任何事件處理程序。這是基本相同的:
$('#some-button').click(function() {
//do something when #some-button is clicked
});
你的第二個:
$('#some-button').live('click', function() {
//do something when #some-button is clicked
});
有live
行爲。它在文檔上安裝一個事件處理程序,並等待針對與「#some-button」相匹配的對象的點擊,直到文檔對象。你的第二個理論上是相同的:
$(document).on('click', '#some-button', function() {
//do something when #some-button is clicked
});
我說的是理論上等效的,因爲它應該安裝相同的事件處理程序,但我不知道如果要處理兩個jQuery的代碼是相同的或沒有。
.live()
已被棄用的原因之一是,有很多.live()
處理程序可能是一件壞事,因爲您在文檔對象上獲得大量事件處理程序。然後,每次點擊甚至鼠標移動到文檔對象都必須對照很多選擇器進行檢查,這可能會減慢速度。
.live()
的另一個問題是,它在您撥打電話時評估選擇器「#some-button」,但實際上並未使用該結果,因此很浪費。 .on()
版本不會評估當您進行第一次調用時作爲參數傳遞給.on()
的選擇器,因爲此時不需要它 - 只是稍後當實際點擊進入時必須與選擇器進行比較。
隨着.on()
出現(或東西,你可以事先與.delegate()
做),你可以不把他們所有的文檔對象,而是把他們一個父對象上更有效地定位您的「活」的事件處理程序不來來去去,接近了很多,其中真正的對象是像這樣的:
$('#some-button-parent').on('click', '#some-button', function() {
//do something when #some-button is clicked ///////
});
這種傳播的事件處理程序到不同的對象,並讓他們更接近他們所意味着的意思的實際對象你不會得到這個巨大的事件處理程序列表,這些事件處理程序必須在每個鼠標移動或點擊事件中與選擇器進行檢查。這就是爲什麼.live()
已被替換和棄用。使用.delegate()
或.on()
並指定與文檔對象距離不遠的父對象會更好。
新的.on()
語法的優點是您可以使用現在相同的方法執行「活動」和「靜態」事件處理程序,只需通過改變傳遞參數的方式即可。 jQuery對象是將安裝事件處理程序的位置,第二個參數中的可選選擇器是事件目標必須匹配的選擇器。如果你傳遞了這個選擇器,那麼所有事件觸發jQuery對象中指定的對象將檢查他們的目標對選擇器。如果沒有選擇器,那麼只有目標對象與jQuery對象中指定的對象相同纔會匹配。
所以,這是關於它們如何工作以及爲什麼一個配置應該比另一個更好的理論。如果你想測試真實世界的性能,你可能需要在事件處理程序傳播和分發方面設計一些性能測試,可能在你有很多「活」事件處理程序的情況下。該測試可能並不容易,因爲可能很難在事件處理程序的開始/結束處獲取計時信息。你不能像jsperf這樣的工具輕鬆地使用這樣的東西。
最好的辦法是火候。 – Blender 2011-12-17 00:56:53
第一個執行更好,因爲您將處理程序直接綁定到元素(而不是文檔根目錄)。你正在比較蘋果和橘子。將處理程序綁定到目標元素越近,它就越早執行。這對他的應用程序性能的影響取決於它本身以及您正在使用的DOM樹。 – 2011-12-17 00:58:49
同樣重要的是,「.live()」有點愚蠢,因爲jQuery必須在原始調用中實際構建選擇器的元素列表,但是然後該元素列表基本上被忽略。 「.live()」API基本上是一個糟糕的設計,自引入「.delegate()」以來,就沒有理由使用它。 – Pointy 2011-12-17 01:03:08