前言
2020 秋天,我將用 30 天的時間,來嘗試回答和網路前端開發相關的 30 個問題。30 天無法一網打盡浩瀚的前端知識,有些問題可能對有些讀者來說相對簡單,不過期待這趟旅程,能幫助自己、也幫助讀者打開不同的知識大門。有興趣的話,跟著我一起探索吧!
今天想要來討論關於 Event capturing and bubbling 的一些事情。不過關於 capturing, bubbling, delegation, preventDefault, stopPropagation 等主題,已經有許多文章討論過,建議可以閱讀以下兩位大大的文章:
那麼,今天到底要討論什麼呢?
相信我們以前都看過這張圖,說明 event capturing 和 bubbling 的過程
但是我心中一直有一個疑問:
為什麼不是先進行 event bubbling,然後才是 capturing?
然後另外一個問題是
如果是先進行 event capturing,那瀏覽器是如何找到 event 發生的節點呢?
於是我開始尋找答案。有一種說法是,當 event 發生之後,瀏覽器會從 root 開始詢問是否有收到 event,如果有就繼續往下找,直到找到產生該 event 的 node 為止。但這樣的意思代表
但感覺不太合理,因為會產生延伸的問題,像是
因此我又繼續尋找答案,後來找到 A crash course in how DOM events work 這篇文章,當中說明,當 event 產生的時候,會經過以下階段
所以當事件在 target node 發生之後,下一步,就會開始往 parent node 一路往上,直到 root。在遍歷 parent node 的過程中,會同時記錄下「路徑」,抵達 root 之後,就會根據剛剛記錄下的「路徑」,開始往下執行 capture phase。
這個解釋我認為是比較可以接受的。不過實際查看 WHATWG 文件 的時候,其實還沒有理解 path
或 composedPath()
當中的內容。如果有看得懂的大大,再請不吝賜教 <(_ _)>
不過這樣還是不能解決剛剛的另外一個問題:為什麼先執行 capturing 後才執行 bubbling?假如 path 有被計算出來,那麼不管要先前進還是先後退應該都是可行的。
另外,在 What is event bubbling and capturing? 這裡的問答當中有提到,最一開始不是所有瀏覽器都同時支援 event capturing 和 bubbling 的功能。Netscape 支持 event capturing,而 IE 則是支持 event bubbling。不過兩種方式都有被記錄在 DOM 的標準文件當中。
結果講到這邊,還是沒辦法完整解答我一開始提出的問題。不過希望能讓更多人帶著這個問題與好奇心,期待有朝一日真的能夠解開謎底!
TD
Be curious as astronomer, think as physicist, hack as engineer, fight as baseball player"Life is like riding a bicycle. To keep your balance, you must keep moving."