---
# System prepended metadata

title: DOM 的事件傳遞機制：捕獲與冒泡
tags: [Frontend]

---

# DOM 的事件傳遞機制：捕獲與冒泡


###### tags:`Frontend`
[TOC]

> 資料來源:[TechBridge 技術共筆部落格(https://blog.techbridge.cc/2017/07/15/javascript-event-propagation/)
> [MTR05]捕獲與冒泡特別補充 也有解說

文章寫得很清楚，裡面的 JS Bin 在理解事件傳遞機制的時候超好用，建議多玩玩它，這邊先記錄一下我初閱時一些常搞混的概念。

* 事件的傳遞與 EventListener 沒關係
* 元素重疊時(是指畫面上的重疊，不是程式碼的巢狀結構)的多重 EventListener 觸發，跟事件的傳遞沒關
* `e.preventDefault`與`e.stopPropagation` 是完全不相關的兩件事

## 簡單介紹事件的傳遞

![範例](https://i.imgur.com/53NhnhZ.jpg)

* ABC 是巢狀的程式碼，當在 C 上面點選的時候，事件的傳遞如圖片(圖片很簡潔，完整版去看文章)，需要注意的是 C 上面究竟是先發生 捕獲 還是先發生 冒泡，是由程式碼的先後來決定。
* > 補充: [chrome 更新後有變動](https://juejin.cn/post/6965682915141386254)

* 冒泡或捕獲可以用`e.eventPhase`來查看，或是用 useCapture 參數來指定發生捕獲或冒泡時的行為 ↓
```javascript=
target.addEventListener(type, listener, useCapture, wantsUntrusted)
```
> useCapture 參數可以指定，default 是 false，也就是使用capture.

* 實作方面，只要在 A 上面加個 EventListener 就可以捕獲到 ABC 的事件。

## 事件的傳遞與 EventListener 沒關係

這點從上一張圖 ↑可以說明，點選 C 之後，就算沒有加 EventListener，事件還是有在正常傳遞。

同理，你也可以在 A 上面加上 eventListener 去監聽 C 的 click 事件。

## 元素重疊時的多重 EventListener 觸發，跟事件的傳遞沒關

> 元素重疊是指畫面上的重疊，不是程式碼的巢狀結構

![範例2](https://i.imgur.com/eVBsI3r.jpg)

當點選到 A 區塊的時候，由於 ABC 區塊是重疊的，所以 ABC 都加上 EventListener 的時候會一起被觸發。

## `e.preventDefault`與`e.stopPropagation` 是完全不相關的兩件事

### `e.preventDefault`

紫色箭頭處加上`e.preventDefault`，==事件的傳遞不受影響，但是 C 的預設行為會被取消==。
> 注意：一旦 call 了preventDefault，在之後傳遞下去的事件裡面也會有效果。

![](https://i.imgur.com/KwK2J7w.jpg)

### `e.stopPropagation`

紫色箭頭處加上`e.stopPropagation`，事==件的傳遞會被中斷，但如果有其他平行的事件則不受影響==。
![](https://i.imgur.com/lLia6SB.jpg)
