首先我们应该要明白DOM事件流可以分为三个阶段分别是捕获阶段,目标阶段,冒泡阶段。
假如有这三个元素
<style>
#box2 {
width: 500px;
height: 500px;
background-color: green;
}
#box1 {
width: 400px;
height: 400px;
background-color: blue;
}
#box0 {
width: 300px;
height: 300px;
background-color: red;
}
</style>
<div id="box2">
<div id="box1">
<div id="box0"></div>
</div>
</div>
事件冒泡
事件捕获阶段就是从触发事件元素,一级一级往上找父元素触发同名事件,如果有就触发。
那么对应三面的三个元素就是会先触发id="box0"的事件然后是id="box1"的事件最后是id="box2"的事件。
为三个元素绑定上点击事件来测试一下
<script>
document.getElementById("box2").addEventListener("click", function(e) {
console.log("box2-on")
}, false)
document.getElementById("box1").addEventListener("click", function(e) {
console.log("box1-on");
}, false)
document.getElementById("box0").addEventListener("click", function(e) {
console.log("box0-on");
}, false)
</script>
页面如下:点击红色区域之后控制台会依次打出
说明默认情况下事件的触发是绑定在冒泡阶段的。
事件捕获
事件捕获阶段就是从最顶级的父元素一级一级往下找子元素触发同名事件,直到触发事件的元素为止。
那么对应三面的三个元素就是会先触发id="box2"的事件然后是id="box1"的事件最后是id="box0"的事件。
之前以及了解过了事件的触发是在冒泡阶段那该如何将事件的触发设置在捕获阶段呢?
其实只要是通过addEventListener(event,fn,useCapture)函数绑定的方法就可以设置为捕获的触发方式,该函数的第三个参数useCapture为是否使用捕获方式触发事件,其默认值为false,那么只要设置为true即可。
设置代码如下:
<script>
document.getElementById("box2").addEventListener("click", function(e) {
console.log("box2-on")
}, true)
document.getElementById("box1").addEventListener("click", function(e) {
console.log("box1-on");
}, true)
document.getElementById("box0").addEventListener("click", function(e) {
console.log("box0-on");
}, true)
</script>
接着点击最里面的元素,控制台就会打印出阻止事件的传播
有些情况下面在真实的开发环境中会需要阻止事件的冒泡或者捕获,这时候就该使用到事件对象中的stopPropagation()函数了。
代码如下:
<script>
document.getElementById("box2").addEventListener("click", function(e) {
console.log("box2-on");
}, true)
document.getElementById("box1").addEventListener("click", function(e) {
console.log("box1-on");
e.stopPropagation();//添加该语句阻止事件继续传播
}, true)
document.getElementById("box0").addEventListener("click", function(e) {
console.log("box0-on");
}, true)
</script>
结果如下:
则说明冒泡传播到id="box1"这一层的时候就停止往下传播了。