最近中文字幕高清中文字幕无,亚洲欧美高清一区二区三区,一本色道无码道dvd在线观看 ,一个人看的www免费高清中文字幕

章節(jié)
問答
課簽
筆記
評(píng)論
占位
占位

委托實(shí)現(xiàn)

在執(zhí)行事件的時(shí)候,jQuery 會(huì)根據(jù)事件綁定的時(shí)候處理來執(zhí)行事件的逐漸觸發(fā),我們觀察一組代碼:

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

給 div 元素綁定一個(gè) mousedown 事件,但是在 div 元素上觸發(fā)的時(shí)候,其實(shí)之前還會(huì)先觸發(fā) li、ul、a,3 個(gè)元素的事件,這是因?yàn)槭录际墙壎ǖ乃膫€(gè)事件,3 個(gè)是通過委托到 div 元素上觸發(fā)的,那么這個(gè)委托是如何處理的?

設(shè)計(jì)的思路解析:

委托的實(shí)現(xiàn)說起來很簡(jiǎn)單,我們事件對(duì)象里面不是有一個(gè) target 屬性嗎? target 就指的觸發(fā)的目標(biāo)對(duì)象。

target 的理解:

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

這個(gè)處理 jQuery 交給了 $.event.handlers 方法,就上一個(gè)結(jié)構(gòu)我們 handlers 這樣分解

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

那么過濾之后的結(jié)構(gòu)就是這樣了:通過 handlerQueue 保存需要的委托隊(duì)列數(shù)據(jù)


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

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

我們按照委托的順序遍歷這個(gè)結(jié)構(gòu)

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();
}

因?yàn)榻Y(jié)構(gòu)上來說,同一個(gè) div 上綁定多個(gè)委托元素,那么事件對(duì)象引用就是同樣的,event.isPropagationStopped 引用永遠(yuǎn)是 div 的事件對(duì)象 div,ul與 p 都是共用的,只是在不同的元素上面修改delegateTarget 與 currentTarget,所以在之前重寫的事件對(duì)象就發(fā)揮作用了,如果在一個(gè)元素上調(diào)用了stopPropagation 那么后面的事件自然都不會(huì)觸發(fā)了,因?yàn)?event.isPropagationStopped 會(huì)獲取這個(gè)狀態(tài)
總的來說 jQuery.event.handlers 做的事情:

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

 

任務(wù)

?不會(huì)了怎么辦
||

提問題

寫筆記

公開筆記
提交
||

請(qǐng)驗(yàn)證,完成請(qǐng)求

由于請(qǐng)求次數(shù)過多,請(qǐng)先驗(yàn)證,完成再次請(qǐng)求

加群二維碼

打開微信掃碼自動(dòng)綁定

您還未綁定服務(wù)號(hào)

綁定后可得到

  • · 粉絲專屬優(yōu)惠福利
  • · 大咖直播交流干貨
  • · 課程更新,問題答復(fù)提醒
  • · 賬號(hào)支付安全提醒

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

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

邀請(qǐng)您關(guān)注公眾號(hào)
關(guān)注后,及時(shí)獲悉本課程動(dòng)態(tài)

舉報(bào)

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

手記推薦

更多

本次提問將花費(fèi)2個(gè)積分

你的積分不足,無法發(fā)表

為什么扣積分?

本次提問將花費(fèi)2個(gè)積分

繼續(xù)發(fā)表請(qǐng)點(diǎn)擊 "確定"

為什么扣積分?