iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 25
1
Modern Web

前端開發 30 個問題系列 第 25

Event capturing and bubbling

  • 分享至 

  • xImage
  •  

前言
2020 秋天,我將用 30 天的時間,來嘗試回答和網路前端開發相關的 30 個問題。30 天無法一網打盡浩瀚的前端知識,有些問題可能對有些讀者來說相對簡單,不過期待這趟旅程,能幫助自己、也幫助讀者打開不同的知識大門。有興趣的話,跟著我一起探索吧!

今天想要來討論關於 Event capturing and bubbling 的一些事情。不過關於 capturing, bubbling, delegation, preventDefault, stopPropagation 等主題,已經有許多文章討論過,建議可以閱讀以下兩位大大的文章:

那麼,今天到底要討論什麼呢?

相信我們以前都看過這張圖,說明 event capturing 和 bubbling 的過程

但是我心中一直有一個疑問:

為什麼不是先進行 event bubbling,然後才是 capturing?

然後另外一個問題是

如果是先進行 event capturing,那瀏覽器是如何找到 event 發生的節點呢?

How to find the path to the target node?

於是我開始尋找答案。有一種說法是,當 event 發生之後,瀏覽器會從 root 開始詢問是否有收到 event,如果有就繼續往下找,直到找到產生該 event 的 node 為止。但這樣的意思代表

  1. event 已經先從 target node 傳遞到 root
  2. 同時,經過的 node 都會記錄下「event 通過的紀錄」

但感覺不太合理,因為會產生延伸的問題,像是

  1. node 哪時候會清除 event 通過的紀錄?
  2. 如果有很多 event? 同時發生並通過同一個 node,要如何判斷哪個紀錄是屬於哪一個 events?

因此我又繼續尋找答案,後來找到 A crash course in how DOM events work 這篇文章,當中說明,當 event 產生的時候,會經過以下階段

  1. 建立 event object
  2. 計算 path
  3. 執行 capture phase
  4. 執行 target phase
  5. 執行 bubble phase
  6. 執行 default browser behavior

所以當事件在 target node 發生之後,下一步,就會開始往 parent node 一路往上,直到 root。在遍歷 parent node 的過程中,會同時記錄下「路徑」,抵達 root 之後,就會根據剛剛記錄下的「路徑」,開始往下執行 capture phase。

這個解釋我認為是比較可以接受的。不過實際查看 WHATWG 文件 的時候,其實還沒有理解 pathcomposedPath() 當中的內容。如果有看得懂的大大,再請不吝賜教 <(_ _)>

不過這樣還是不能解決剛剛的另外一個問題:為什麼先執行 capturing 後才執行 bubbling?假如 path 有被計算出來,那麼不管要先前進還是先後退應該都是可行的。

Other story

另外,在 What is event bubbling and capturing? 這裡的問答當中有提到,最一開始不是所有瀏覽器都同時支援 event capturing 和 bubbling 的功能。Netscape 支持 event capturing,而 IE 則是支持 event bubbling。不過兩種方式都有被記錄在 DOM 的標準文件當中。

End

結果講到這邊,還是沒辦法完整解答我一開始提出的問題。不過希望能讓更多人帶著這個問題與好奇心,期待有朝一日真的能夠解開謎底!

Ref


TD
Be curious as astronomer, think as physicist, hack as engineer, fight as baseball player

More about me

"Life is like riding a bicycle. To keep your balance, you must keep moving."


上一篇
如何調整游標 (caret) 位置
下一篇
JavaScript abstract equality comparison
系列文
前端開發 30 個問題31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言