事件流描述的就是从页面中接收事件的顺序。而IE和Netscape提出了完全相反的事件流概念。IE事件流是事件冒泡,而Netscape的事件流就是事件捕获。
事件捕获
事件捕获的思想是不太具体的节点应该更早的接收到事件,而在最具体的节点应该最后接收到事件。事件捕获的用以在于 事件到达预定目标之前 捕获它。从window开始捕获(尽管DOM2级事件规范要求从document)。由于老版本浏览器不支持,所以很少有人使用事件捕获。
事件冒泡
IE的事件流叫做事件冒泡。即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档)。所有现代浏览器都支持事件冒泡,并且会将事件一直冒泡到window对象。
实例
还是来具体实操吧
HTML:
<html>
<body>
<div class="div1">
div1
<div class="div2">
div2
<div class="div3">
div3
</div>
</div>
</div>
</body>
</html>
CSS:
.div1 {
position: relative;
width: 300px;
height: 300px;
background: grey;
}
.div2 {
width: 200px;
height: 200px;
background: yellow;
}
.div3 {
width: 100px;
height: 100px;
background: red;
}
.div2,
.div3 {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%)
}
JS:
function getElement(className) {
return document.querySelector(className)
}
const div1 = getElement('.div1');
const div2 = getElement('.div2');
const div3 = getElement('.div3');
div1.addEventListener('click', () => {
console.log('bubble event: div1 click')
});
div1.addEventListener('click', () => {
console.log('capture event: div1 click')
}, true);
div2.addEventListener('click', () => {
console.log('bubble event: div2 click')
});
div2.addEventListener('click', () => {
console.log('capture event: div2 click')
}, true);
div3.addEventListener('click', () => {
console.log('bubble event: div3 click')
});
div3.addEventListener('click', () => {
console.log('capture event: div3 click')
}, true);
点击红色区域,会输出哪些log信息?
"capture event: div1 click"
"capture event: div2 click"
"bubble event: div3 click"
"capture event: div3 click"
"bubble event: div2 click"
"bubble event: div1 click"
解析
一共3个div,每个div我们都分别在它的冒泡阶段和捕获阶段注册了监听器,所以当我们点击红色区域时(此时事件预定目标为'div3')
第一阶段:事件捕获阶段(到达预订目标(div3)之前) 依次输出
"capture event: div1 click"
"capture event: div2 click"
第二阶段:目标阶段(div3) 依次输出
"bubble event: div3 click"
"capture event: div3 click"
第三阶段:事件冒泡阶段 (到达预订目标(div3)之后) 依次输出
"bubble event: div2 click"
"bubble event: div1 click"
思考题
在事件到达 预订目标div3 时,为什么先输出"bubble event: div3 click"再输出"capture event: div3 click"
Demo
补充知识点:
addEventListener方法属于DOM二级,使用时如果不提供第三个参数,默认是在冒泡阶段触发
有问题的小伙伴可以留言,欢迎交流