事件:JavaScript和HTML之间的交互是通过事件实现的
事件流:描述的是页面接受事件的顺序
事件捕获:不太具体的节点先接受到事件,最具体的节点最后接收到事件(顺序:window document html body div)
事件冒泡:文档嵌套最深的节点先接收,然后逐级向上传播到不具体的节点(顺序:div body html document window)
DOM事件流:包括事件捕获阶段、目标阶段和事件冒泡阶段;执行顺序是:事件捕获(为截获事件提供机会)、目标阶段(目标接收事件) 冒泡阶段(事件做出响应)
例子:
<style>
#a{
width: 300px;
height: 300px;
background: pink;
}
#b{
width: 200px;
height: 200px;
background: blue;
}
#c{
width: 100px;
height: 100px;
background: yellow;
}
</style>
<body>
<div id="a">
<div id="b">
<div id="c"></div>
</div>
</div>
<script>
var a = document.getElementById("a"),
b = document.getElementById("b"),
c = document.getElementById("c");
c.addEventListener("click", function (event) {console.log("c1");});
c.addEventListener("click", function (event) {console.log("c2");}, true);
b.addEventListener("click", function (event) {console.log("b");}, true);
a.addEventListener("click", function (event) {console.log("a1");}, true);
a.addEventListener("click", function (event) {console.log("a2")});
a.addEventListener("click", function (event) {console.log("a3");
event.stopImmediatePropagation();
},
true);
a.addEventListener("click", function (event) {console.log("a4");}, true);
</script>
1:当点击a时,输出结果是:a1 a2 a3
因为点击a,此时已经属于目标阶段,既不是捕获阶段,也不是冒泡阶段。在目标阶段,事件是按照注册的顺序而执行,所以是a1 a2 a3;
2:当点击b或c时,输出的结果是:a1 a3
因为a中有event.stopImmediatePropagation(),他会/阻止事件冒泡并且阻止相同事件的其他侦听器被调用,所以不会打印a4,以及b和c上的事件也会被阻止;
3:注释掉event.stopImmediatePropagation(),点击c,输出的结果是:a1 a3 a4 b c1 c2 a2
为什么是c1在c2前面?因为在c上,是处于目标阶段,既不是捕获阶段,也不是冒泡阶段。在目标阶段,事件是按照注册的顺序而执行,所以是c1 c2.
补充:addEventListener的第三个参数如果是true:事件在捕获阶段执行;如果是false:事件在冒泡阶段执行;