Event Object
- Handler function 會帶的參數
1 | const btn = document.queryselector('.btn'); |
- e.target
- 指向綁定該 handler 的 DOM (上例中即 btn)
Event propogation
兩個大原則
- 先向下捕獲,再向上冒泡
- 當事件傳到 target 本身,不分捕獲或冒泡
捕獲
- 當一個事件(e.g. click)發生時, 事件會從
window
開始向下傳遞, 直到傳到 target
冒泡
- 當事件傳到 target 後, 接著會向上冒泡, 直到回到 window
三個 Phase
- event object 中包含了一個 propery: eventPhase
1 | const unsigned short CAPTURING_PHASE = 1; |
- 當 Event 在向下捕獲時,Event Object 處於
CAPTURING_PHASE
- 當 Event 到達 target 時,Event Object 處於
AT_TARGET
- 當 Event 向上冒泡時,Event Object 處於
BUBBLING_PHASE
(From W3C - eventflow)
.addEventlistener() 的第三個參數
決定這個 handler 要在何時執行
- true: 在捕獲階段時執行
- false(default): 在冒泡階段時執行
直接看例子
1 |
|
1 | const get = id => document.getElementById(id); |
當按下超連結時的結果:
1 | list capturing |
先執行了掛在 capture phase 的 handler, 接著執行 target 的 handler (不管是掛在 capturing or bubbling,
都屬於 AT_TARGET
), 最後執行 bubling phase handler[注意注意]
- Event 在傳遞的過程中, 途中經過的各個 DOM handler 之中的
this
均指向該 DOM
, 但是 e.target 均是指向最終的目標
- Event 在傳遞的過程中, 途中經過的各個 DOM handler 之中的
e.stopPropagation()
- 取消事件
向下(or 向上)
傳遞 - 上述例子中修改為
1 | $list.addEventListener('click', (e) => { |
Event 停止向下傳遞, 結果為
1 | list capturing |
e.preventDefault()
- 取消預設行為
- <a>: 點擊時超連結行為
- <form>: 送出表單的行為
1 | document.querySelector('a').addEventListener('click', (e) => { |
- 當向下捕獲時有節點的 handler 執行了 e.preventDefault(), 之後接到該 Event 的節點
都會被取消預設行為
- 當上述例子在 #list 的 handler 加上 preventDefault, 事件傳到 #list_item_link 即失去了 <a> tag 超連結的預設行為
參考文獻
- DOM 的事件傳遞機制:捕獲與冒泡
- NTHU Course - Software studio