亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

章節
問答
課簽
筆記
評論
占位
占位

委托實現

在執行事件的時候,jQuery 會根據事件綁定的時候處理來執行事件的逐漸觸發,我們觀察一組代碼:

div.on('mousedown', 'li', function(e) {
  show('委托到li觸發')
})
div.on('mousedown', 'ul', function(e) {
  show('委托到ul觸發')
})
div.on('mousedown', 'a', function(e) {
  show('委托到a觸發')
})
div.on('mousedown', function(e) {
  show('mousedown')
})

給 div 元素綁定一個 mousedown 事件,但是在 div 元素上觸發的時候,其實之前還會先觸發 li、ul、a,3 個元素的事件,這是因為事件都是綁定的四個事件,3 個是通過委托到 div 元素上觸發的,那么這個委托是如何處理的?

設計的思路解析:

委托的實現說起來很簡單,我們事件對象里面不是有一個 target 屬性嗎? target 就指的觸發的目標對象。

target 的理解:

<ul>
 <li>點擊執行委托鏈</li>
</ul>
  1. 給 ul 綁定一個事件,那么點擊 li 的時候 li 就是目標對象
  2. 如果給 li 綁定一個事件,點擊 li 目標對象就是自身了
通過 target 與實際的事件綁定對象我們就可以劃分一個區域段,通過遞歸獲取每一個元素的 parentNode 節點,在每一個節點層上通過與委托節點的對比用來確定是不是委托的事件元素,這個就是委托的核心思路了

這個處理 jQuery 交給了 $.event.handlers 方法,就上一個結構我們 handlers 這樣分解

  1. 點擊觸發事件,觸發任意一個 target 元素
  2. 通過遞歸回溯 target.parentNode 來找到 li 元素或者 ul 元素,當然遞歸的最終直到 div 節點
  3. 如果在任意個遞歸中找到了委托的節點那么就這個元素給保存起來,這里暫時不處理,這樣我們先確定好這個觸發的隊列數據
簡單來說就是把 target 到根節點 div 通過 node.parentNode 遍歷一遍,然后找到對應的委托元素節點,如果符合就緩存起來用于之后的操作,可以通過 jQuery.event.handlers 方法我們可以獲取類似這種的一組數據結構

那么過濾之后的結構就是這樣了:通過 handlerQueue 保存需要的委托隊列數據


從這里我們可以看出 delegate 綁定的事件和普通綁定的事件是如何分開的,對應一個元素一個 event.type 的事件,處理對象隊列在緩存里只有一個,按照冒泡的執行順序與元素的從內向外遞歸以及 handlers 的排序,所以就處理了,就形成了事件隊列的委托在前,自身事件在后的順序,這樣也跟瀏覽器事件執行的順序一致了。

區分delegate綁定和普通綁定的方法是:delegate 綁定從隊列頭部推入,而普通綁定從尾部推入,通過記錄 delegateCount 來劃分,delegate 綁定和普通綁定

我們按照委托的順序遍歷這個結構

while ((matched = handlerQueue[i++]) && !event.isPropagationStopped()) {
  event.currentTarget = matched.elem;
  j = 0;
  while ((handleObj = matched.handlers[j++]) && !event.isImmediatePropagationStopped()) {
      ret = handleObj.handler.apply(matched.elem, args);
      //如果返回了false
      if (ret !== undefined) {
        if ((event.result = ret) === false) {
          event.preventDefault();
          event.stopPropagation();
}

因為結構上來說,同一個 div 上綁定多個委托元素,那么事件對象引用就是同樣的,event.isPropagationStopped 引用永遠是 div 的事件對象 div,ul與 p 都是共用的,只是在不同的元素上面修改delegateTarget 與 currentTarget,所以在之前重寫的事件對象就發揮作用了,如果在一個元素上調用了stopPropagation 那么后面的事件自然都不會觸發了,因為 event.isPropagationStopped 會獲取這個狀態。
總的來說 jQuery.event.handlers 做的事情:

  1. 將有序地返回當前事件所需執行的所有事件處理程序。
  2. 這里的事件處理程序既包括直接綁定在該元素上的事件處理程序,也包括利用冒泡機制委托在該元素的事件處理程序(委托機制依賴于 selector)。
  3. 在返回這些事件處理程序時,委托的事件處理程序相對于直接綁定的事件處理程序在隊列的更前,委托層次越深,該事件處理程序則越靠前。

 

任務

?不會了怎么辦
||

提問題

寫筆記

公開筆記
提交
||

請驗證,完成請求

由于請求次數過多,請先驗證,完成再次請求

加群二維碼

打開微信掃碼自動綁定

您還未綁定服務號

綁定后可得到

  • · 粉絲專屬優惠福利
  • · 大咖直播交流干貨
  • · 課程更新,問題答復提醒
  • · 賬號支付安全提醒

收藏課程后,能更快找到我哦~

使用 Ctrl+D 可將課程添加到書簽

邀請您關注公眾號
關注后,及時獲悉本課程動態

舉報

0/150
提交
取消
全部 精華 我要發布
全部 我要發布
最熱 最新
只看我的

手記推薦

更多

本次提問將花費2個積分

你的積分不足,無法發表

為什么扣積分?

本次提問將花費2個積分

繼續發表請點擊 "確定"

為什么扣積分?