JavaScript - DOM 事件傳遞(冒泡 & 捕獲)
當元素綁定的事件被觸發時,會經過三個階段,捕獲階段(CAPTURING_PHASE)、目標階段(AT_TARGET)與冒泡階段(BUBBLING_PHASE)。
事件傳遞
首先看看事件傳遞的表現,在 HTML 中設定一個外部元素 outer
與內部元素 inner
。
1 | <div class="outer"> |
將兩個元素分別綁定點擊事件。
1 | const outer = document.querySelector(".outer") |
執行的結果 :
可以發現,當內部元素 inner
被點擊時,在 console 中不只印出 “inner”,也印出了 “outer”,這顯示出當在觸發內部元素事件的同時,外部元素的相同事件也會一起被觸發。
傳遞階段
DOM 事件傳遞分成三個階段 :
- 捕獲階段(CAPTURING_PHASE) : 事件從
window
向下傳遞到目標元素的過程。 - 目標階段(AT_TARGET) : 事件傳遞到目標本身。
- 冒泡階段(BUBBLING_PHASE) : 事件由目標向上傳遞回
window
。
在 addEventListener()
回調函式中,可以通過事件物件 e
的 eventPhase
屬性,確認當前事件在傳遞中的哪一個階段被觸發。
而 addEventListener()
的第三個參數為 useCapture
,意思是 listener 是否在捕獲階段被觸發。若為 true
,即決定回調函式觸發於捕獲階段,為 false
則觸發於冒泡階段。
用與上例相同的 HTML 結構,看看以下範例 :
1 | const outer = document.querySelector(".outer") |
當點擊內部元素 inner
後,得到的結果為 : ( 1
: 捕獲階段,2
: 目標階段,3
: 冒泡階段。)
1 | "outer CAPTURING:" 1 |
可以看到首先事件捕獲到外部元素 outer
,接著來到目標元素 inner
,最後再冒泡傳回 outer
。
而在過程中內部元素的 eventPhase
都是 2
,也就是說當事件已經傳到目標身上進入目標階段(AT_TARGET)時,就沒有捕獲與冒泡的分別。