jq父級繫結事件的意義 事件委託和JQ事件繫結總結

2021-10-13 03:16:44 字數 2950 閱讀 7016

事件委託:

比喻:事件委託的事例在現實當中比比皆是。比如,有三個同事預計會在周一收到快遞。為簽收快遞,有兩種辦法:一是三個人在公司門口等快遞;二是委託給前台mm代為簽收。現實當中,我們大都採用委託的方案(公司也不會容忍那麼多員工站在門口就為了等快遞)。前台mm收到快遞後,她會判斷收件人是誰,然後按照收件人的要求簽收,甚至代為付款。這種方案還有乙個優勢,那就是即使公司裡來了新員工(不管多少),前台mm也會在收到寄給新員工的快遞後核實並代為簽收。

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

.bind()

1 $("info_table td").bind("click", function() );

問題是,如果**中要繫結單擊事件的有10列500行,那麼查詢和遍歷5000個單元格會導致指令碼執行速度明顯變慢,而儲存5000個td元素和相應的事件處理程式也會占用大量記憶體(類似於讓每個人親自站在門口等快遞)。

事實卻不然。使用.bind()方法只會給第一頁中的50個單元格繫結單擊事件,動態載入的後續頁面中的單元格都不會有這個單擊事件。換句話說,.bind()只能給呼叫它的時候已經存在的元素繫結事件,不能給未來新增的元素繫結事件(類似於新來的員工收不到快遞)。

live()----------die()詳細解說位址

事件委託可以解決上述兩個問題。具體到**上,只要用jquery 1.3新增的.live()方法代替.bind()方法即可:

1 $("#info_table td").live("click",function());

到目前為止,一切似乎很完美。可惜,事實並非如此。因為.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():

1 (function($));3 })(jquery);

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

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

1 $("td",$("#info_table")[0]).live("click",function());

delegate()    仔細講解鏈結

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

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

1 $("#info_table").delegate("td","click",function());

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

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

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

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

one() 方法為被選元素附加乙個或多個事件處理程式,並規定當事件發生時執行的函式。

當使用 one() 方法時,每個元素只能執行一次事件處理器函式。

toggle()

toggle()方法用於繫結兩個或多個事件處理器函式,以響應被選元素的輪流的 click 事件。

trigger()

方法觸發被選元素的指定事件型別。

與 trigger() 方法相比的不同之處

它不會引起事件(比如表單提交)的預設行為

.trigger() 會操作 jquery 物件匹配的所有元素,而 .triggerhandler() 只影響第乙個匹配元素。

由 .triggerhandler() 建立的事件不會在 dom 樹中冒泡;如果目標元素不直接處理它們,則不會發生任何事情。

該方法的返回的是事件處理函式的返回值,而不是具有可鏈性的 jquery 物件。此外,如果沒有處理程式被觸發,則這個方法返回 undefined。

另:事件源

ie下 event.srcelement

ff下 event.target

jq父級繫結事件的意義 兩種語法糖,搞定雙向繫結

無論是vue還是react,在父子元件通訊的時候,子元件都禁止直接修改父級傳過來的prop,父元件總需要在子元件身上監聽乙個事件,然後由子元件去觸發它,好讓父元件來接收到payload去改變state。能不能直接在子元件裡修改prop,然後父元件中的state也隨之改變呢?其實本質上是不行的,但幸運...

事件繫結與事件委託

事件繫結 為什麼要用到事件繫結?我的理解是同乙個物件無法新增多個事件?如果新增多個事件的話按照執行順序來說下邊的事件會把上面的替換 就像以下 var odiv document.getelementbyid div1 odiv.onclick function odiv.onclick functi...

JQ 事件繫結與事件委派

一 定義 所謂事件 即給相應標籤進行的動作 二 事件繫結 給所有的p標籤繫結乙個事件click,去執行裡邊的function函式 p click function 三 事件委派 1 定義 事件委派的定義就是,把原來加給子元素身上的事件繫結在父元素身上,就是把事件委派給父元素。2 具體執行,用on來繫...