Skip to main content

[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,
})
);