摘要:方法將事件類型和一個事件處理函數直接注冊到了被選中的元素中。方法將與事件處理函數關聯的選擇器和事件信息一起附加到文檔的根級元素即。通過將事件信息注冊到上,這個事件處理函數將允許所有冒泡到的事件調用它例如委托型傳播型事件。
簡介
我了解到很多網頁開發者對jquery中的 .bind() .live() .delegate() 和 .on() 方法存在很多的疑惑。這些疑惑通常是關于它們之間真正的區別是什么啊,什么時候該使用它們啊。
在我們深入了解這些方法之前,我們先來一段常見的的HTML,作為我們編寫jquery示例方法使用的樣本。
使用Bind方法.bind()方法將事件類型和一個事件處理函數直接注冊到了被選中的DOM元素中。這個方法被使用得最久,在此期間,它很好的解決了各種跨瀏覽器的問題。當使用它來連接事件處理函數時,它仍然非常簡潔,但是也存在著一些性能方面的問題,將在下面羅列出來。
/* .bind() 方法將事件類型和一個事件處理函數直接注冊到了被選中的DOM元素中。 .click() 方法只是.bind() 方法的簡寫。 */ $( "#members li a" ).bind( "click", function( e ) {} ); $( "#members li a" ).click( function( e ) {} );
.bind()方法將會把事件處理函數連接到所有匹配的a標簽。這種方式并不好。這樣做的話,它不僅在所有匹配的元素中隱含地迭代附加事件處理函數,而且這些操作非常浪費(多余),因為這些相同的事件處理函數是被一遍一遍的重復的添加到所有匹配的標簽上。
優點:
適用于各種瀏覽器
連接事件處理函數非常方便快捷
可以使用 .click(), .hover()等簡寫方法來更方面地連接事件處理函數
對于一個簡單的ID選擇器,使用.bind() 方法不僅可以很快地連接事件處理函數,而且當事件被觸發時, 事件處理函數幾乎是馬上就被調用了
缺點:
這樣方法會將所有的事件處理函數附加到所有匹配的元素
不可以動態地匹配相同選擇器的元素
當操作大量匹配的元素時會有性能方面的問題
附加操作是在前期完成的,這可能導致頁面加載時存在性能問題
使用Live方法.live()方法使用了事件委托的概念來實施其所謂的“魔法”。你調用.live()方法的方式就像是調用.bind()方法那樣方便。然而在這表面之下,.live()方法與前者的實現方式大不相同。.live()方法將與事件處理函數關聯的選擇器和事件信息一起附加到文檔的根級元素(即document)。通過將事件信息注冊到document上,這個事件處理函數將允許所有冒泡到document的事件調用它(例如委托型、傳播型事件)。一旦有一個事件冒泡到document元素上,Jquery會根據選擇器或者事件的元數據來決定哪一個事件處理函數應該被調用,如果這個事件處理函數存在的話。這個額外的工作將會在用戶交互時對性能方面造成一定的影響,但是初始化注冊事件的過程相當地快。
/* 方法將與事件處理函數關聯的選擇器和事件信息一起附加到文檔的根級元素(即document) ( "#members li a" & "click" ) */ $( "#members li a" ).live( "click", function( e ) {} );
.bind()這個例子與上面.bind()方法的例子對比的話有一個優點在于它僅僅把事件處理函數附加到document元素一次,而不是很多次。這樣不僅更快,而且還減少了性能的浪費。然而,使用這個方法也會帶來很多問題,下面將一一列出。
優點:
所有的事件處理函數都只會被注冊一次,而不是像.bind()那樣進行多次注冊
將.bind()方法升級到.live()方法非常方便,你僅需要將"bind"替代為"live"就可以了
那些被動態添加到DOM的元素也將被神奇的匹配到,因為真實的事件信息是被注冊到document元素上的
你可以在文檔加載完之前連接事件處理函數,這樣可以幫助你更好地利用你可能沒有用的時間
缺點:
這個方法在Jquery 1.7以后的版本被棄用了,你應該在你的代碼里逐步放棄使用它
使用這個方法時鏈式操作沒有得到正確的支持,可能會出現某些錯誤
所做的匹配操作基本上沒用因為它只用于在document元素上注冊事件處理函數
使用 event.stopPropogation() 方法將會沒用,因為事件總是已經被委托到了document元素上
因為所有的選擇器或者事件信息都被附加到document元素上了,所以一旦有一個事件要調用某個事件處理函數,Jquery會在一大堆儲存的元數據中使用matchesSelector方法來決定哪一個事件處理函數將會被調用,如果這個函數有的話。
因為你所連接的事件總是被委托到document上,所如果你的DOM的層級很深的話,這會導致一定的性能問題
使用Delegate方法.delegate()方法與.live()方式實現方式相類似,它不是將選擇器或者事件信息附加到document,而是讓你指定附加的元素。就像是.live()方法一樣,這個方法使用事件委托來正確地工作。
如果你跳過了前面關于 .live() 方法的介紹,你可能要回去重新看看它,因為這里涉及到之前我所闡述的一些內部邏輯
/* .delegate() 方法會將選擇器和事件信息 ( "li a" & "click" ) 附加到你指定的元素上 ( "#members" )。 */ $( "#members" ).delegate( "li a", "click", function( e ) {} );
.delegate()方法十分強大。在上面這個例子中,與事件處理函數關聯的選擇器和事件信息將會被附加到( #members" )這個元素上。這樣做比使用.live()高效多了,因為.live()方法總是將與事件處理函數關聯的選擇器和事件信息附加到document元素上。另外,使用.delegate()方法解決許多其他問題。請參閱下方列出的詳細信息。
優點:
你可以選擇將選擇器或者事件信息附加到指定的元素。
匹配操作實際上在前面并沒有執行,而是用來注冊到指定的元素。
鏈式操作可以得到正確的支持
Jquery仍然需要迭代這些選擇器或者事件信息來匹配元素,不過因為你可以選擇哪一個元素作為根元素,所以篩選的量會大幅減少
因為這項技術使用了事件委托機制,它可以匹配到被動態地添加到DOM的元素
你可以在文檔加載完之前連接事件處理函數
缺點:
從.bind()方法不可以直接升級到.delegate()方法
Jquery仍然需要使用marchesSelector方法在附加到指定根元素的選擇器或者事件信息中篩選決定哪一個事件處理函數會被調用。然而,附加到指定根元素的元數據會比使用.live()方法的時候要小得多。
當操作大量匹配的元素時會有性能方面的問題
附加操作是在前期完成的,這可能導致頁面加載時存在性能問題
使用On方法你知道嗎,在Jquery 1.7版本中.bind(),.live() 和.delegate()方法只需要使用.on()方法一種方式來調用它們。當然.unbind(),.die() 和.undelegate()方法也一樣。一下代碼片段是從Jquery 1.7版本的源碼中截取出來的
bind: function( types, data, fn ) { return this.on( types, null, data, fn ); }, unbind: function( types, fn ) { return this.off( types, null, fn ); }, live: function( types, data, fn ) { jQuery( this.context ).on( types, this.selector, data, fn ); return this; }, die: function( types, fn ) { jQuery( this.context ).off( types, this.selector || "**", fn ); return this; }, delegate: function( selector, types, data, fn ) { return this.on( types, selector, data, fn ); }, undelegate: function( selector, types, fn ) { return arguments.length == 1 ? this.off( selector, "**" ) : this.off( types, selector, fn ); }
考慮到這一點,使用.on()方法看起來像以下方式一樣...
/* Jquery的 .bind() , .live() 和 .delegate() 方法只需要使用`.on()`方法一種方式來調用它們 */ // Bind $( "#members li a" ).on( "click", function( e ) {} ); $( "#members li a" ).bind( "click", function( e ) {} ); // Live $( document ).on( "click", "#members li a", function( e ) {} ); $( "#members li a" ).live( "click", function( e ) {} ); // Delegate $( "#members" ).on( "click", "li a", function( e ) {} ); $( "#members" ).delegate( "li a", "click", function( e ) {} );
你可能注意到了,我如何使用.on()方法決定了它如何調用其他方法。你可以認為.on()方法被具有不同簽名的方法”重載“了,而這些方法實現了不同的事件綁定的連接方式。.on()方法的出現為API帶來了很多方面的一致性,并希望讓事情變得不那么混亂。
優點:
使各種事件綁定方法一致。
因為在Jquery源碼中.bind(),.live() 和.delegate()方法實際上是調用了此方法,因此簡化了jQuery代碼庫并刪除了一級重定向。
這種方式仍然提供了使用.delegate()方法的優點,并且仍然提供對.bind()方法的支持,如果你需要的話。
缺點:
給人帶來了一些疑惑,因為方法的實際執行方式將根據你如何調用方法而改變。
總結如果你對不同的綁定事件方法有所迷惑,那么不要擔心,因為API發展了一段時間了,有很多前人的經驗可以借鑒。也有很多人將這些方法視為魔法,不過一旦你了解了他們工作背后的原理,將幫助您了解如何更好地處理項目。
以下是這篇文章的精華所在...
使用.bind()方法非常浪費性能因為它把同一個事件處理函數附加到了每一個匹配的元素上
你應該停止使用.live()方法因為它被棄用了同時也會帶來很多問題
使用.delegate()方法會給你帶來很多好處當你需要解決一些性能上的問題和對動態添加的元素作出處理
新的.on()方法其實就是模擬.bind(),.live() 和.delegate()實現的語法糖,具體取決于你如何調用它
新的方向是使用新的.on()方法。先熟悉語法,并開始在你的所有的Jquery 1.7版本以上的項目使用它吧!
對于上面列舉的優點或者缺點,你有新的補充嗎?你最近開始使用.delegate()方法了嗎?你對新的.on()方法怎么看呢?把你的想法寫到用評論告訴我吧!謝謝!
第一次翻譯,文章中可能會出現一些不通順的地方,希望得到大家的理解,畢竟我還是個學生??!
原文鏈接
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/84534.html
摘要:方法用到了事件委托的概念來處理事件的綁定??梢杂迷趧討B添加的元素上缺點需要查找那個那個元素上發生了那個事件了,盡管比少很多了,不過,你還是得浪費時間來查找。 當我們試圖綁定一些事件到DOM元素上的時候,通常會使用以下的四個方法bind(),on(),live(),delegate()大家應該用的較多的是前兩種方法。下面是我對四種方法的理解: Bind(): .bind()是最直接的綁定...
摘要:但是當我們點擊新添加的元素也就是時,卻沒有把這個加給它。它的原理是利用事件冒泡最終代理給最頂層的。對于動態生成的元素也生效因為其實是綁定在上的。 假設我們有這樣一段html: book 1 book 2 add a li 1: .bind().bind方法的用法是這樣的:targetElment.bind(eventType, eventHandler)所以假入我...
摘要:它是一個過濾器的作用,只有被選中元素的后代元素才會觸發事件。替換是引入的,目的是通過祖先元素來代理委派后代元素的事件綁定問題,某種程度上和優點相似。相關資料深入理解新的綁定事件機制方法的使用新的事件綁定機制 前言 在開發項目的時候,JQuery的使用極其廣泛,如果腦海中沒有一點JQuery的基礎知識,隨性編寫,那么就有可能造成bug問題。JQuery 1.4版本之后新增了on方法,這個...
摘要:它是一個過濾器的作用,只有被選中元素的后代元素才會觸發事件。替換是引入的,目的是通過祖先元素來代理委派后代元素的事件綁定問題,某種程度上和優點相似。相關資料深入理解新的綁定事件機制方法的使用新的事件綁定機制 前言 在開發項目的時候,JQuery的使用極其廣泛,如果腦海中沒有一點JQuery的基礎知識,隨性編寫,那么就有可能造成bug問題。JQuery 1.4版本之后新增了on方法,這個...
摘要:它是一個過濾器的作用,只有被選中元素的后代元素才會觸發事件。替換是引入的,目的是通過祖先元素來代理委派后代元素的事件綁定問題,某種程度上和優點相似。相關資料深入理解新的綁定事件機制方法的使用新的事件綁定機制 前言 在開發項目的時候,JQuery的使用極其廣泛,如果腦海中沒有一點JQuery的基礎知識,隨性編寫,那么就有可能造成bug問題。JQuery 1.4版本之后新增了on方法,這個...
閱讀 2432·2021-11-22 13:53
閱讀 1126·2021-09-22 16:06
閱讀 1370·2021-09-02 15:21
閱讀 1895·2019-08-30 15:55
閱讀 3116·2019-08-29 11:19
閱讀 1911·2019-08-26 13:23
閱讀 931·2019-08-23 18:23
閱讀 1748·2019-08-23 16:06