[JS30] Day25: Event Capture, Propagation, Bubbling and Once
這一天主要是學習,當我們在元素上面裝監聽器時,事件會如何被觸發,孰先孰後,HTML 架構如下,有三個層層包覆的div
<div class="one">
<div class="two">
<div class="three"></div>
</div>
</div>
Bubbling
當我們在每個div
元素都裝監聽器,我們點擊最內層.three
時,會發現 console 新增了三條內容
three
two
one
const divs = document.querySelectorAll("div");
function logText(e) {
console.log(e.target.classList.value);
}
divs.forEach((div) => div.addEventListener("click", logText));
這是所謂的Bubbling,點擊內層元素會往外擴散
Event Capture
在上個範例中,點擊元素時,,由內往外觸發事件(bubbling),而我們可以透過監聽器的第三個參數內的capture
來設定,瀏覽器會記住由外往內點擊的元素
divs.forEach((div) =>
div.addEventListener("click", logText, {
capture: true, // default is false
})
);
這時候,我們點擊.three
,會發現 console 新增了三條內容
one
two
three
Propagation
透過e.stopPropagation()
,會使得事件不會 bubbling,觸發上層元素的事件
function logText(e) {
console.log(this.classList.value);
e.stopPropagation(); // stop bubbling!
divs.forEach(div => div.addEventListener('click', logText, {
capture: false,
}));
這時候,我們點擊.three
,會發現 console 新增了一條內容
three
Once
在addEventListener
的第三個參數加入once: true
,會使得這個監聽器只觸發一次,觸發一次後就回移除此監聽器。
divs.forEach((div) =>
div.addEventListener("click", logText, {
capture: false,
once: true,
})
);