Phoenix's Blog

JavaScript | event bubbling & capture

2019-09-06

[JavaScript] - event bubbling & capture

開始了解 BubblingCapturing 之前,一定要先玩完 addEventListener監聽事件,

addEventListener 使用方法

1
addEventListener('事件型態','方法',[true/false])
  • 事件型態:最常用的點擊事件’click’、…等
  • 方法:監聽到事件後,要觸發的 function()
  • 第三個參數分為 true/ false
    • true: 添加到 Capturing (捕獲)階段
    • false:添加到 Bubbling (冒泡)階段

Bubbling 冒泡事件實戰

首先我們先把三個 div 疊起來並將監聽 addEventListener 第三個參數設為 false 像底下範例圖:

html:

1
2
3
4
5
6
<div class ="blueBox" style="width: 100px;height:100px; background-color: blue">
<div class ="yellowBox" style="width: 70px;height: 70px; background-color: yellow">
<div class ="greenBox" style="width: 50px;height: 50px; background-color: green">
</div>
</div>
</div>

js:

1
2
3
4
5
6
7
8
9
10
11
12
var blueBox = document.querySelector('.blueBox');
var yellowBox = document.querySelector('.yellowBox');
var greenBox = document.querySelector('.greenBox');
greenBox.addEventListener('click',function(e){
console.log('green-Bubbling');
},false);
yellowBox.addEventListener('click',function(e){
console.log('yellow-Bubbling');
},false);
blueBox.addEventListener('click',function(e){
console.log('blue-Bubbling');
},false);

當點擊綠色時 console 會依序印出:

1
2
3
green-Bubbling
yellow-Bubbling
blue-Bubbling

這就是所謂的 冒泡事件,一層一層的「由內而外」的冒泡出去,那接下來我們將 false 改成 true 看看捕捉事件並印出來

Capturing 捕捉事件實戰

這邊程式碼與上方相同,只將第三個參數改成 true

1
2
3
4
5
6
7
8
9
10
11
12
var blueBox = document.querySelector('.blueBox');
var yellowBox = document.querySelector('.yellowBox');
var greenBox = document.querySelector('.greenBox');
greenBox.addEventListener('click',function(e){
console.log('green-Capturing');
},true);
yellowBox.addEventListener('click',function(e){
console.log('yellow-Capturing');
},true);
blueBox.addEventListener('click',function(e){
console.log('blue-Capturing');
},true);

這次一樣點擊綠色的 div 並印出結果:

1
2
3
blue-Capturing
yellow-Capturing
green-Capturing

捕捉事件是從「由外而內」一層一層的捕捉

但我們再用下方程式來看,將每個 <div> 都加上 BubblingCapturing

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
greenBox.addEventListener('click',function(e){
alert('greenBox!!!');
console.log('green-Capturing ');

},true);
greenBox.addEventListener('click',function(e){
alert('greenBox!!!');
console.log('green-Bubbling');

},false);
yellowBox.addEventListener('click',function(e){
alert('yellowBox!!!');
console.log('yellow-Capturing ');
},true);
yellowBox.addEventListener('click',function(e){
alert('yellowBox!!!');
console.log('yellow-Bubbling');
},false);
blueBox.addEventListener('click',function(e){
alert('blueBox!!!');
console.log('blue-Capturing ');
},true);
blueBox.addEventListener('click',function(e){
alert('blueBox!!!');
console.log('blue-Bubbling');
},false);

而 console 印出來的結果是:

1
2
3
4
5
6
blue-Capturing 
yellow-Capturing
green-Capturing
green-Bubbling
yellow-Bubbling
blue-Bubbling

取消事件傳遞

根據上面印出的結果,我們可子看到了很多文章中提到的「先捕捉,再冒泡

但是若我們不想點擊一個物件後卻像漣漪一直將事件傳遞出去時,我們可以透過 e.stopPropagation取消事件傳遞,而將他加在哪,哪裡就會中斷事件傳遞.

因「先捕捉,再冒泡」,我們將 e.stopPropagation 加在 blue

1
2
3
4
5
6
7
8
.
.
blueBox.addEventListener('click',function(e){
console.log('blue-Capturing ');
e.stopPropagation();
},true);
.
.

點擊綠色區塊並印出結果:

1
blue-Capturing

從結果看到事件在藍色區塊的 Capturing 階段就被停止傳遞了,可以了解到加入 e.stopPropagation(); 時會不會再將事件傳遞給下一個節點.

參考:DOM 的事件傳遞機制:捕獲與冒泡

tags: JavaScript Bubbling Capturing