JS趴趴往上走-DOM傳遞機制
Event Bubbling & Event Capturing
要了解捕獲與冒泡機制之前首先我們要知道事件是怎麼處理的大家還記得DOM是一層一層下來的
<html>
<head>
<title>網頁標題</title>
</head>
<body>
<h1>Header</h1>
<a href="#">快速連結</a>
</body>
</html>
對應的的圖片:
而他們重疊的樣子就是
所以當你點擊目標(
target
)時,在這邊我們假設點擊了<a>
連結,其實除了<a>
被點擊之外,包含它的<body>
其實也被點擊了哦,<html>
、document
也被點擊了,會一層一層往上找所以我們可以知道點擊了一個
<a>
,有包覆它的元素也會跟著被點擊,可以說是整個網頁都被點擊了!那麼除了目標之外,有包覆著他的都會被點擊,那它們是誰先傳遞續訊息呢?
DOM在傳遞訊息順序有兩種方法:
事件冒泡 Event Bubbling
事件捕獲 Event Capturing
Event Bubbling
事件冒泡是指,當您點擊目標元素後,會一層一層往上傳遞,直到最上面的根結點,就是我們的document
以下面範例來說:
<html>
<head>
<title>網頁標題</title>
</head>
<body>
<ul>
<li></li>
<li></li>
<li><a href="#"></a></li>
</ul>
</body>
</html>
當我們點擊
<a>
,而冒泡機制就會是<a>
→ <li>
→ <ul>
→ <body>
→ <html>
→ <document>
逐漸往上觸發
Event Capturing
事件捕獲就和事件冒泡相反,是從上往下觸發所以以上範例來講,點擊目標
<a>
它會是<document>
→ <html>
→ <body>
→ <ul>
→ <li>
→ <a>
觸發優先順序
事件捕獲和事件冒泡兩個機制對於事件都會執行,沒有特別依賴哪種,但當兩種機制若是一起觸發的話事件會先捕獲,再冒泡
我們看之前
addEventListener()
範例(建議點進去看console.log()
)當兩種事件都被觸發時,外層捕獲會優先執行,再到內層,這邊提醒:內層對於點擊的目標是沒有分順序的!誰程式碼優先,就先執行,之後再換外層冒泡執行
終止捕獲、冒泡
現在我們知道點擊內部,外面也會被觸發,那怎麼阻止這種事發生,就可以使用Event.stopPropagation()
Event.stopPropagation():可以阻止當前事件繼續進行捕獲及冒泡階段的傳遞
以下範例來看(建議點進去看
console.log()
)當你的
Event.stopPropagation()
放在哪邊,事件的傳遞就斷在哪裡,不會繼續往下傳遞假如:
console.log("我是外面捕獲!!!")
放置Event.stopPropagation()
,當點擊我在裡面的div
,你會發現console.log()只會顯示"我是外面捕獲!!!"
因為當點擊目標時,你上面的也會跟著點擊,以先捕獲再冒泡,所以會先顯示
"我是外面捕獲!!!"
,接著"我是外面捕獲!!!"
有放置Event.stopPropagation()
,所以傳遞斷掉了,故只顯示"我是外面捕獲!!!"
所以說,若你是把
Event.stopPropagation()
放在console.log('我是裡面冒泡!!!');
或者 console.log('我是裡面捕獲!!!');
就會依序得到"我是外面捕獲!!!"
、"我是裡面冒泡!!!"
、"我是裡面捕獲!!!",
而"我是外面冒泡!!!"
因為被中斷了所以不會顯示Event.stopPropagation()
(建議點進去看console.log()
)只能中斷你想中斷的那個節點而已,若是你想要讓其他同一層級的也不要被執行,可以改用e.stopImmediatePropagation();
這邊提醒,同一層級是按照程式碼優先依序執行的,若你
Event.stopImmediatePropagation();
寫在同層級的最後一個,前面一樣還是會被執行哦資料來源:
https://blog.techbridge.cc/2017/07/15/javascript-event-propagation/
https://ithelp.ithome.com.tw/articles/10191970?sc=iThelpR
留言
張貼留言