1. 程式人生 > >jquery live() delegate() on() 事件委託的一些區別

jquery live() delegate() on() 事件委託的一些區別

隨著DOM結構的複雜化和Ajax等動態指令碼技術的運用,有了較多的動態新增進來的元素,直接用JQ新增click事件會發現新新增進來的元素並不能直接選取到,在這裡就需要用到事件委託方法,JQ為事件委託提供了live()、dalegate()和on()方法。   

事件委託

我們知道,DOM在為頁面中的每個元素分派事件時,相應的元素一般都在事件冒泡階段處理事件。在類似 body > div > a 這樣的結構中,如果單擊a元素,click事件會從a一直冒泡到div和body(即document物件)。因此,發生在a上面的單擊事件,div和body元素同樣可以處理。而利用事件傳播(這裡是冒泡)這個機制,就可以實現事件委託。具體來說,事件委託就是事件目標自身不處理事件,而是把處理任務委託給其父元素或者祖先元素,甚至根元素(document)。

.live()

jQuery 1.3新增的live()方法,用法如下:

$("#info_table td").live("click",function(){/*顯示更多資訊*/});

這裡的.live()方法會把click事件繫結到$(document)物件,而且只需要給$(document)繫結一次,然後就能夠處理後續動態載入的單元格的單擊事件。在接收到任何事件時,$(document)物件都會檢查事件型別和事件目標,如果是click事件且事件目標是td,那麼就執行委託給它的處理程式。

到目前為止,一切似乎很完美。可惜,事實並非如此。因為.live()方法並不完美,它有如下幾個主要缺點:

  • $()函式會找到當前頁面中的所有td元素並建立jQuery物件,但在確認事件目標時卻不用這個td元素集合,而是使用選擇符表示式與event.target或其祖先元素進行比較,因而生成這個jQuery物件會造成不必要的開銷;

  • 預設把事件繫結到$(document)元素,如果DOM巢狀結構很深,事件冒泡通過大量祖先元素會導致效能損失;

  • 只能放在直接選擇的元素後面,不能在連綴的DOM遍歷方法後面使用,即$("#infotable td").live...可以,但$("#infotable").find("td").live...不行;

  • 收集td元素並建立jQuery物件,但實際操作的卻是$(document)物件,令人費解。

解決之道

為了避免生成不必要的jQuery物件,可以使用一種叫做“早委託”的hack,即在$(document).ready()方法外部呼叫.live():

(function($){
    $("#info_table td").live("click",function(){/*顯示更多資訊*/});
})(jQuery);

在此,(function($){...})(jQuery)是一個“立即執行的匿名函式”,構成了一個閉包,可以防止命名衝突。在匿名函式內部,$引數引用jQuery物件。這個匿名函式不會等到DOM就緒就會執行。注意,使用這個hack時,指令碼必須是在頁面的head元素中連結和(或)執行的。之所以選擇這個時機,因為這時候剛好document元素可用,而整個DOM還遠未生成;如果把指令碼放在結束的body標籤前面,就沒有意義了,因為那時候DOM已經完全可用了。

為了避免事件冒泡造成的效能損失,jQuery從1.4開始支援在使用.live()方法時配合使用一個上下文引數:

$("td",$("#info_table")[0]).live("click",function(){/*顯示更多資訊*/});

這樣,“受託方”就從預設的$(document)變成了$("#infotable")[0],節省了冒泡的旅程。不過,與.live()共同使用的上下文引數必須是一個單獨的DOM元素,所以這裡指定上下文物件時使用的是$("#infotable")[0],即使用陣列的索引操作符來取得的一個DOM元素。

.delegate()

如前所述,為了突破單一.bind()方法的侷限性,實現事件委託,jQuery 1.3引入了.live()方法。後來,為解決“事件傳播鏈”過長的問題,jQuery 1.4又支援為.live()方法指定上下文物件。而為了解決無謂生成元素集合的問題,jQuery 1.4.2乾脆直接引入了一個新方法.delegate()。

使用.delegate(),前面的例子可以這樣寫:

$("#info_table").delegate("td","click",function(){/*顯示更多資訊*/});

使用.delegate()有如下優點(或者說解決了.live()方法的如下問題):

  • 直接將目標元素選擇符("td")、事件("click")及處理程式與“受拖方”$("#info_table")繫結,不額外收集元素、事件傳播路徑縮短、語義明確;

  • 支援在連綴的DOM遍歷方法後面呼叫,即支援$("table").find("#info").delegate...,支援精確控制;

可見,.delegate()方法是一個相對完美的解決方案。但在DOM結構簡單的情況下,也可以使用.live()。

提示:使用事件委託時,如果註冊到目標元素上的其他事件處理程式使用.stopPropagation()阻止了事件傳播,那麼事件委託就會失效。

 在下列情況下,應該使用.live()或.delegate(),而不能使用.bind():

  • 為DOM中的很多元素繫結相同事件;

  • 為DOM中尚不存在的元素繫結事件;

 .on()

根據jQuery 1.7 Beta 1的發版說明,jQuery 1.7為了解決.bind()、.live()和.delegate()並存造成的不一致性問題,將會增加一對新的事件方法:.on()和.off(),以下為on()的實現方式:

.on( events [, selector ] [, data ], handler(eventObject) )

一個簡單的事件繫結如 $('button').on('click',function(){}); 與bind()無二樣。
在需要為較多的元素繫結事件的時候,優先考慮事件委託,可以帶來效能上的好處。比如:
 

 

如上圖,將click事件繫結在document物件上,頁面上任何元素髮生的click事件都冒泡到document物件上得到處理。

注意到.on()的描述中第二個可選引數:selector。如下圖,添加了第二個引數,選擇符button:

 結果:

當事件冒泡到document物件時,檢測事件的target,如果與傳入的選擇符(這裡是button)匹配,就觸發事件,否則不觸發。 

注意.on()也可以接收一個物件引數,該物件的屬性是事件型別,屬性值為事件處理函式。下面是官方文件的一個例子:

最後有一點,原先的live()方法,處理函式是預設繫結在document物件上不能變的,如果DOM巢狀結構很深,事件冒泡通過大量祖先元素會導致較大的效能損失。而使用.on()方法,事件只會繫結到$()函式的選擇符表示式匹配的元素上(上面我的例子中,為了簡單繫結到了document),因此可以精確地定位到頁面中的一部分,而事件冒泡的開銷也可以減少。delegate()與on()同理,畢竟是用on()實現的:

 .on()和.off():實現方式
$(elems).on(events, selector, data, fn);
$(elems).off(events, selector, fn);
如果指定selector,則為事件委託;否則,就是常規繫結。新舊API對應如下:

相關推薦

jquery live delegate on() 事件委託一些區別

隨著DOM結構的複雜化和Ajax等動態指令碼技術的運用,有了較多的動態新增進來的元素,直接用JQ新增click事件會發現新新增進來的元素並不能直接選取到,在這裡就需要用到事件委託方法,JQ為事件委託提供了live()、dalegate()和on()方法。    事件委託 我們知道,DOM在為頁面中的

設計模式之業務代表模式Business Delegate Pattern

業務代表模式(Business Delegate Pattern)用於對錶示層和業務層解耦。它基本上是用來減少通訊或對錶示層程式碼中的業務層程式碼的遠端查詢功能。在業務層中我們有以下實體。 客戶端(Client) - 表示層程式碼可以是 JSP、servlet 或 UI java 程式碼。

jQuery中bind,oneonlive這幾個繫結事件函式的區別

1、bind()方法 為每個匹配元素的特定事件繫結事件處理函式。bind()方法的底層邏輯是on()方法。 .bind() 方法是用於往文件上附加行為的主要方式。所有JavaScript事件物件,比如focus, mouseover, 和 resize,都是可以作為type引數傳遞進來

jQuery中的事件委派代理事件delegate

jQuery給我們提供了強大的js庫。我們可以用jQuery指令碼向頁面新增元素,隨著程式進行新增的元素怎麼新增事件呢?就需要使用delegate了。 delegate() 方法可以為已有或新新增的頁面元素繫結已定義的事件:如下:html: <body><div><spa

jquery繫結事件優化網頁效能使用on進行事件委託

自身認知限制,在之前做專案使用jquery框架的時候會直接使用$(obj).click(function(){})(click可以換成其他的事件)為目標物件繫結事件,並沒有覺得有什麼不妥。今天看了一篇部落格驚著了。原來光是知其然,不知其所以然。 例子如下:在頁面中新增10

jQuery基礎常用插件 表單驗證,圖片放大鏡,自定義對象級,jQuery UI,面板折疊

此外 cookie值 添加圖標 tor 列表 需要 droppable 使用 ddn 1.表單驗證插件——validate 該插件自帶包含必填、數字、URL在內容的驗證規則,即時顯示異常信息,此外,還允許自定義驗證規則,插件調用方法如下: $(form).vali

jquery 獲取及操作元素 常用

.com pre img htm color hello fun 文檔 wid jquery 獲取元素 參考:http://www.w3school.com.cn/jquery/jquery_selectors.asp 1.(1)$(document).ready()

jQuery架構設計與實現2.1.4版本

需要 引入 hasclass 8.4 uri and hub 組織 移除 市面上的jQuery書太多了,良莠不齊,看了那麽多總覺得少點什麽 對"幹貨",我不喜歡就事論事的寫代碼,我想把自己所學的知識點,代碼技巧,設計思想,代碼模式能很好的表達出來,所以考慮通過分析jQuer

jquery+bootstrap做一個開關互斥選擇

utf jquer class role 選擇 span chrome query back 知識點:js中的return 不能使js程序停止或者跳出執行,會繼續往下執行。要想讓js程序停止或者跳出 可以用 return false 就可以了。 代碼: <!-----

jQuery UI 日期選擇器Datepicker

jquery ui next ext style cti cto log href region 設置JqueryUI DatePicker默認語言為中文 <!doctype html><html lang="en"> <head&g

js源碼 模仿 jquery的ajax的獲取數據get,post 的請求封裝

{} req turn eva syn 動作 取字符串 func ring function ajax(obj){ // 默認參數 var defaults = { type : ‘get‘, data : {}, url : ‘#‘, dataType : ‘text‘,

html+css+jquery 實現模態盒模式窗口對話框

weight data- 動畫 lac .com 按鈕 oot display spl 最近在實現一些jQuery相關的組件,既是為了熟悉一下 jQuery 的語法,也是為了能夠了解一些 jQuery 插件底層的基本實現。 今天花了一些時間做的一個模態盒(這是谷歌翻譯的名字

Delegate委托

類型 簽名 多線程 bsp sta eal static his 太陽 在前面lambda章節中稍微提了一下委托,今天這章就讓我們來深究一下委托。 委托的本質是一種類,他是繼承MulticastDelegate類的。 而聲明委托的關鍵字的delegate,如:public

jQuery源代碼解析1—— jq基礎、data緩存系統

代碼解析 post 方法 step 作用域鏈 垃圾清理 版本 get initial 閑話 jquery 的源代碼已經到了1.12.0 版本號。據官網說1版本號和2版本號若無意外將不再更新,3版本號將做一個架構上大的調整。但預計能兼容IE6-8的。或許

jQuery 分頁插件jQuery.pagination.jsajax 實現分頁

height var 實現 before 狀態 pin 好的 調用 是否 首先需要引入jQuery 再次需要引入 <script src="jquery/jquery.pagination.js"></script>同時也要引入 <link r

Jquery EasyUI Tree樹形結構的Java實現實體轉換VO

優勢 con control 項目 util turn ttr real org 前一陣做的OA項目,有一個是組織架構的樹,因為是分開做的,我做的是Controller和頁面,其他組做的Service和Dao,因為之前一直沒有商量頁面用什麽框架做比較好,導致,Dao層取出來

uva live 7638 Number of Connected Components 並查集

txt 通過 open main eps div cte efi ive 題目鏈接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_

uva live 7637 Balanced String 貪心

std sta print names case push live gif map 題目鏈接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page

jQuery源代碼解析3—— ready載入、queue隊列

else ng- settime eve ref promise ont 出隊 function ready、queue放在一塊寫,沒有特殊的意思,僅僅是相對來說它倆可能源代碼是最簡單的了。ready是在dom載入完畢後。以最高速度觸發,非常實用。que

c#中的delegate委托和event事件

sel 指針 添加 自動 關鍵字 only cnblogs 私有 part 委托: 托付其他人做這件事 ,包括 托付自己 ,即 一個方法 可以 調用 沒有關系的其他方法 , 也可以 將委托傳遞過去 ,回調自己的方法 ,且 可以自定義參數 ,非常方便 互相傳值, 適