事件是用户或者浏览器自己执行的某种动作,是文档或者浏览器发生的一些交互瞬间,比如点击(click)、指针悬浮(mouseover)、提交(submit)等,这是JavaScript 与 HTML 交互的基础,要实现用户与页面的交互,需要先对目标元素绑定特定的事件以及设置事件处理函数,然后用户触发事件执行事件处理函数,最后产生交互效果。我们都知道DOM是一种树形结构,那么当触发某个元素的时候其父辈元素也被认为触发了吗?例如当点击某个元素的时候,其父辈元素也被认为点击了吗?答案是当触发某个元素的时候其父辈元素也会同时触发,这样就会产生一个执行顺序的问题,是自上而下(从父辈元素开始)还是自下而上(从当前元素开始)执行呢?
要回答上面的问题,就需要了解DOM事件中的事件流,事件流描述的就是从页面中接受事件的顺序,DOM2级事件规定事件流包括三个阶段: 事件捕获(capturing phase)、目标事件(target phase)、事件冒泡(bubbling phase),示意图如下所示:

事件捕获:事件按 window -> document -> html -> body -> ... -> 目标元素 的方向向下层元素传递。
其中的addEventListener()函数的第三个参数为true时表示事件在捕获阶段执行,为false时表示事件在冒泡阶段执行。

<body\>

 <div id\="outer"\>

 <div id\="inner"\></div\>


</div\>

 <script\>

 let body = document.body;

 let outer = document.getElementById('outer');

 let inner = document.getElementById('inner');

 body.addEventListener('click', () \=> {

 console.log('i am body');

 }, true)  //为true时表示在捕获阶段执行

 outer.addEventListener('click', () \=> {

 console.log('i am outer');

 }, true)

 inner.addEventListener('click', () \=> {

 console.log('i am inner');

 }, true)

 </script\>

</body\>

当点击元素inner时,打印的结果为:
image.png
事件冒泡:事件开始时由最具体的元素(目标元素)接收,然后逐级向上传播。

<body\>

 <div id\="outer"\>

 <div id\="inner"\></div\>

 </div\>

 <script\>

 let body = document.body;

 let outer = document.getElementById('outer');

 let inner = document.getElementById('inner');

 body.addEventListener('click', () \=> {

 console.log('i am body');

 }, false)   //为false表示在冒泡阶段执行

 outer.addEventListener('click', () \=> {

 console.log('i am outer');

 }, false)

 inner.addEventListener('click', () \=> {

 console.log('i am inner');

 }, false)

 </script\>

</body\>

点击inner元素的执行结果:
image.png

上述代码可以很好地展示出捕获与冒泡的区别,这两个阶段在每一次事件处理中都会经历,先经历捕获阶段,然后再经历冒泡阶段,通过设置addEventListener()函数的第三个参数来决定事件在哪一个阶段执行。

参考文章:
https://juejin.im/post/5ce7a7...
https://juejin.im/post/5c4bd0...


belaxie
1 声望0 粉丝