事件冒泡与捕获
概念
事件冒泡:触发事件后,从目标(触发事件的组件)向外(祖先组件)传播
事件捕获:触发事件后,从目标的根节点向内传播
结论
顺序:捕获 -> 目标 -> 冒泡
如点击事件,
捕获: 点击一个组件后,首先触发其根节点的 捕获事件(如果有),然后依次向内触发目标的各祖先组件的捕获事件。目标: 事件传递到目标后,触发目标的点击事件,目标如果同时定义了 捕获事件,冒泡事件,其执行顺序是按照事件的绑定顺序,而不是先捕获再冒泡。
冒泡: 目标事件触发后,再向根节点传播,触发沿途祖先组件的冒泡事件。
事件默认在冒泡阶段执行。
通过 addEventListener(event, function(){ }, useCapture) 第三个参数设置,默认为 false (冒泡), 可设置为 true (捕获)
验证过程
- 创建嵌套的 HTML
<div id="div4">
<div id="div3">
<div id="div2">
<div id="div1"></div>
</div>
</div>
</div>
<style type="text/css">
div {
border: 1px solid #000;
}
#div4 {
width: 400px;
height: 400px;
background-color: red;
}
#div3 {
width: 300px;
height: 300px;
background-color: yellow;
}
#div2 {
width: 200px;
height: 200px;
background-color: green;
}
#div1 {
width: 100px;
height: 100px;
background-color: blue;
}
</style>
效果:
- 给每个组件添加点击事件
var div1 = document.getElementById('div1');
var div2 = document.getElementById('div2');
var div3 = document.getElementById('div3');
var div4 = document.getElementById('div4');
let t = true;
let f = false;
div1.addEventListener('click', function() {
console.log('1');
},f);
div2.addEventListener('click', function() {
console.log('2');
},f);
div3.addEventListener('click', function() {
console.log('3');
},f);
div4.addEventListener('click', function() {
console.log('4');
},f);
div4 > div3 > div2 > div1
1.
此时:
点击 div4:
点击 div1:
冒泡触发顺序为: div1 -> div2 -> div3 -> div4
2.
然后,将所有的 useCapture 都变为 true,点击 div1:
捕获触发顺序为: div4 -> div2 -> div2 -> div1
3.
然后我们将 1,3 useCapture 变为 false(冒泡),2,4 保持 true(捕获), 点击 div1:
触发顺序为: 先捕获 -> 再冒泡 div4 -> div2 -> div1 -> div3
4.
最后我们将 事件复制4份,冒泡事件输出(1,2,3,4) ,捕获事件输出(11,22,33,44) , 从上到下依次为 冒泡,捕获,冒泡,捕获:
点击 div1:
从外向内每个组件首先触发两次捕获事件,目标阶段的触发顺序与其他不一样,与事件的绑定顺序一致,然后从内向外,每个组件触发两次冒泡事件。