
A Dirty Deal
概述
- 事件根據(jù)事件模型規(guī)定的傳播路徑被逐級(jí)傳遞, 在傳播過程中依次觸發(fā)對(duì)應(yīng)的事件監(jiān)聽器, 然后被繼續(xù)傳遞. 直到完成事件傳播, 或是傳播過程被終止.
事件路徑 和 DOM 分支 ( branch )
- 從事件源所在節(jié)點(diǎn) ( event.target ) 逐級(jí)向上一直追溯到 window 對(duì)象的路徑中的一系列節(jié)點(diǎn), 構(gòu)成了一個(gè) DOM 分支.
- 這個(gè)分支就是該事件傳播的路徑
- 示意圖:
-
在下圖中, <td> 元素就是 事件源所在節(jié)點(diǎn). 它和父級(jí)元素層層向上構(gòu)成了一個(gè)事件在不同階段傳播的路徑.
事件傳播的路徑和事件傳播的三個(gè)階段
-
事件傳播的階段 Event Propagation Phases:
- 事件傳播是JS DOM事件中各階段的概括, 由三個(gè)階段組成:
-
捕獲階段 capture phase
- 事件從 window 對(duì)象逐級(jí)向下傳播, 直到目標(biāo)對(duì)象的父節(jié)點(diǎn)的過程
-
目標(biāo)階段 target phase
- 事件到達(dá)目標(biāo)節(jié)點(diǎn)自身
-
冒泡階段 bubble phase
- 事件從目標(biāo)的父節(jié)點(diǎn)逐級(jí)向上傳播, 一直到達(dá) window 對(duì)象的過程
-
event.target 和 event.currentTarget
- event.target :
- 事件源, 事件傳播路徑的中心
- event.currentTarget:
- 在事件傳播過程中, 每次觸發(fā)監(jiān)聽器時(shí), 監(jiān)聽器所在(綁定)的對(duì)象.
監(jiān)聽器的綁定
- 在一個(gè)節(jié)點(diǎn)上, 可以綁定多個(gè)同類型的事件監(jiān)聽器. 當(dāng)事件傳播到這個(gè)節(jié)點(diǎn)上的時(shí)候, 監(jiān)聽器根據(jù)綁定的先后依次觸發(fā). (隊(duì)列)
不同類型的監(jiān)聽器在三個(gè)階段的表現(xiàn):
- 使用 addEventListener() 綁定事件監(jiān)聽器
target.addEventListener(type, listener[, useCapture])- 捕獲型事件監(jiān)聽器:
- 在 addEventListener() 函數(shù)中, 第三個(gè)參數(shù) (捕獲標(biāo)志位) 為true 的事件監(jiān)聽器.
el.addEventListener('click', listener, true)
- 在 addEventListener() 函數(shù)中, 第三個(gè)參數(shù) (捕獲標(biāo)志位) 為true 的事件監(jiān)聽器.
- 捕獲型事件監(jiān)聽器:
-
捕獲階段:
- 在捕獲階段的路徑中, 捕獲器 ( capturer listener ) 會(huì)主動(dòng)捕獲事件, 然后觸發(fā).
-
目標(biāo)階段:
- 在這個(gè)階段, 目標(biāo)節(jié)點(diǎn)上的所有監(jiān)聽器會(huì)按照綁定的順序依次地觸發(fā).
-
冒泡階段:
- 在這個(gè)階段, 節(jié)點(diǎn)上的非捕獲監(jiān)聽器會(huì)被觸發(fā).
-
不會(huì)冒泡的事件
- 需要注意的是, 有一部分事件是不會(huì)冒泡的:
- 例如 focus, blur, load 事件.
- 因此它們的監(jiān)聽器必須設(shè)置為捕獲器才會(huì)有效.
- 需要注意的是, 有一部分事件是不會(huì)冒泡的:
控制事件傳播
-
event.stopPropagation()
- 事件的傳播路徑停止在當(dāng)前監(jiān)聽器的節(jié)點(diǎn)上.
- 路徑中該位置上的其他同類事件監(jiān)聽器仍然能夠響應(yīng)事件.
-
event.stopImmediatePropagation()
- 事件的傳播立即結(jié)束.
- 該位置上的其他同類事件監(jiān)聽器不會(huì)被觸發(fā)
-
取消事件默認(rèn)行為
- event.preventDefault()
