事件流
什么是事件流:
每个事件发生时,都会有一个触发并执行的过程,也就是事件的传播过程,我们称为事件流;简单来说,事件事件流就是事件从发生到执行结束的流程。
事件流的三个阶段:捕获阶段,目标阶段,冒泡阶段。
事件捕获阶段:事件开始由顶层元素触发,然后逐级向下传播,直到目标元素,依次执行其身上邦定的事件;
事件目标阶段(处理阶段):触发当前自身的事件;
事件冒泡阶段:事件由目标元素先接收,然后逐级向上传播,达到最顶层元素,依次执行其身上绑定的事件。
事件流模型
事件执行的流程是先捕获阶段→再目标元素阶段→最后冒泡阶段。
目标元素的事件是在目标阶段执行,其他事件会在冒泡阶段执行。每个事件只会执行一次,也就是说如果在冒泡阶段执行了事件,就不会在捕获阶段执行。
案例:
设置大中小三个盒子的点击事件
<style> #big{ width: 300px; height: 300px; border:1px solid #000; background:orange; } #middle{ width: 200px; height: 200px; background: #abcdef; } #small{ width: 100px; height: 100px; background: red; } </style> <body> <div id="big"> 大 <div id="middle"> 中 <div id="small"> 小 </div> </div> </div> </body> <script> big.onclick=function(){ console.log(this.innerText); console.log("点击大盒子"); } middle.onclick=function(){ console.log(this.innerText); console.log("点击中盒子"); } small.onclick=function(){ console.log(this.innerText); console.log("点击小盒子"); } </script>
效果
当我们点击小盒子触发点击事件时,发现中盒子跟大盒子的点击事件也被触发了:
当我们点击中盒子触发点击事件时,发现大盒子的点击事件也被触发了:
点击大盒子时只触发了大盒子的点击事件
上面的情况说明:点击小盒子,发现小盒子事件完毕后,中盒子的事件也被触发了,接着大盒子的事件也被触发了。这就是说目标元素的事件在目标阶段执行,其他事件会在冒泡阶段执行。
总之总结成一张图更好理解:
那么如何让事件在捕获阶段执行呢?
需要使用另外一种事件绑定方式解决点击小盒子会同时触发中大盒子的点击事件。
使用addEventListener();解决;
如何使用addEventListener()方法:
obj.addEventListener(type,handle,false);
# 参数1:给元素绑定的事件类型,如:click,mouseover。。。
# 参数2:处理事件的函数
# 参数3:是否在冒泡阶段执行,true在捕获阶段执行,false在冒泡阶段执行
把script中的代码改成:
document.getElementById("small").addEventListener("click",Click,true); function Click(){ console.log(this.innerText); }
效果:
这样就解决了当触发小盒子事件时同时触发大盒子中盒子也会触发点击事件的问题了。