JavaScript 事件傳遞機制:Capturing 與 Bubbling 的執行順序
此文章是 FrontendMaster 上的 Advanced Web Development Quiz 課程筆記
問題
What gets logged when clicking <button>?
Select the correct answer.
javascript
<div class='outer'>
<div class='inner'>
<button>Click me!</button>
</div>
</div>;
outer.addEventListener('click', () => log('A'), true);
outer.addEventListener('click', () => log('B'));
inner.addEventListener('click', () => log('C'), true);
inner.addEventListener('click', (e) => {
log('D');
e.stopPropagation();
log('E');
});
button.addEventListener('click', () => log('F'));
button.addEventListener('click', () => log('G'), true);[1] A B C D E F G
[2] A C G F D
[3] B D E F G C A
[4] A C G F
[5] A C G F D E事件傳遞 (Event Propagation)
這一題在考事件傳遞 (Event Propagation)
我們可以在 DOM 上的任何元素上監聽事件,當某個元素觸發事件時 (例如使用者點擊),瀏覽器會建立從最外層(例如 document/window)到目標元素的傳遞路徑,先走捕獲 (capture) 到達目標,再走冒泡 (bubbling) 回到外層,沿途依序執行符合階段的事件監聽器。
當使用 addEventListener 監聽事件時,第二個參數是當事件被觸發後要執行的 callback,第三個參數如果傳了一個 boolean 就會當作是設定這個 callback 要在捕獲階段還是冒泡階段執行。預設是 false 冒泡階段觸發,所以沒有給第三個參數時,就會是冒泡階段觸發。
stopPropagation
在 addEventListener 裡面的第二個參數是一個 callback,這個 callback 有一個參數可以使用,這個參數是一個 Event 物件,而這個 Event 裡面有一個 stopPropagation 方法,當執行 stopPropagation 時,當執行完當前的 callback 後就會阻止事件傳播(不論當下是在捕獲或冒泡階段皆會停止)。
答案
A C G F D E