iT邦幫忙

2021 iThome 鐵人賽

DAY 13
0
Modern Web

前端藏寶圖系列 第 13

事件迴力鏢 - 捕獲與冒泡

傳遞機制聽起來非常沒有畫面感,於是擅自替傳遞機制取了綽號叫迴力鏢,如同迴力鏢有去程,回程以及獵捕到獵物的瞬間。事件傳遞機制也分成類似的三個階段:

  1. capture phase
  2. target phase
  3. bubbling phase

下圖是W3C的事件流程圖,此圖說明了當使用者點擊td時,Event Object會由Window一路傳遞到td的父層tr,這個過程稱作capture phase,接著到達觸發事件的元素則是target phase,從event target一路回傳的過程則稱為bubbling phase


圖片來源:W3C

為了驗證規範,還是來實做一次吧~( codepen連結

以下先在 html 內各個元素各自綁定事件監聽器,每當元素被點擊,就會跳出視窗告知是哪個元素被點擊以及是在事件流程的哪個階段

const elements = document.querySelectorAll('*')

for (let element of elements) {
    element.addEventListener('click', e => alert(`phase: ${e.eventPhase}, ${element.tagName}`))
}

如果夠仔細的話,會發現不管點擊哪個元素,視窗都沒有跳出第一個階段,這是為什麼呢?

還記得昨天有提到addEventListener()的第三個引數嗎?
當沒有傳入值或設定為false時,代表的是我們把監聽器加到bubbling phase上,只要再多添加一個監聽器,並將第三個引數設定為true,當點擊元素時就可以觀察到完整的迴力鏢過程了。

事件委派

觀察每個介紹事件委派的例子,一定都會提到的狀況就是要對大量的相同元素綁定事件監聽,或是後來新增的元素也需要因應使用者的行為而給予設計好的流程等等。

聰明的程式好手想到的解法便是透過父節點來處理子節點。

對我來說,事件委派的核心精神就是「能坐就不站,能躺就不坐,能做一次的事就不做兩次」。

釐清相似名詞

一開始常常搞不清楚下面三個名詞的差別,在練習的過程中才逐漸察覺如果沒有使用事件委派的話,其實這三個名詞代表的會是同一個元素,但一旦有使用到事件委派,它們各自代表的元素就可能會有如下的差別:

  • event.target: 代表觸發事件的元素
  • event.currentTarget/ this: 代表設置監聽器的元素

如果有同樣困擾的朋友可以搭配 codepen 觀察,相信會清楚許多~

參考資料:
Event order
DOM Event Architecture - W3C
Bubbling and capturing - JAVASCRIPT.INFO
DOM 的事件傳遞機制:捕獲與冒泡


上一篇
老大哥在看著你 - 事件與事件監聽
下一篇
初探 超文本傳輸協定 HTTP
系列文
前端藏寶圖30

1 則留言

0
Hooo
iT邦新手 5 級 ‧ 2021-09-28 18:33:24

codepen 的實作很清楚很棒!!

我要留言

立即登入留言