「这是我参与11月更文挑战的第25天,活动详情查看:2021最后一次更文挑战」
虽然事件捕获在实际开发中很少被用到,但是有时是有用的,所以一起来了解一下吧!
前言
首先需要知道的是,一个事件传播它会有3个阶段
- 捕获阶段(Capturing phase)—— 事件从最上一级标签开始往下查找,直到捕获到事件目标(target)。
- 目标阶段(Target phase)—— 事件到达目标元素。
- 冒泡阶段(Bubbling phase)—— 事件从事件目标(target)开始,往上冒泡直到页面的最上一级标签。
这是一个点击表格<td>的图片(来自👉W3C规范)
可以看到,点击<td>时,
- 事件首先通过祖先链向下到达元素(即红色那路线,Capturing phase【捕获阶段】)
- 然后到达目标(即到达
<td>元素,Target phase【目标阶段】) - 最后又从
td重新回到顶级(即绿色那条路线,Bubbling phase【冒泡阶段】)
假如有一个元素div,它有一个下级元素p
<div id="div">
DIV
<p id="p"> P </p>
</div>
此时,如果给它们都绑定了click事件,哪个元素的click先触发呢?
如果点击P标签,打印的结果是
说明是p先触发,div后触发,这里发生的就是事件冒泡。
冒泡👉【传送门】
如果想要换成事件捕获,也很简单,只需要把addEventListener函数的第三个参数改为true即可。可以试一下
let div = document.getElementById("div")
let p = document.getElementById("p")
function divClick(){ console.log("点击DIV");}
function pClick(){ console.log("点击P标签"); }
div.addEventListener('click', divClick, true);
p.addEventListener('click', pClick, true);
这个时候你在点击P标签,结果是
即div先触发,p后触发,这就是【事件捕获】
总结
-
冒泡 ,内部元素的事件会先被触发,然后再触发外部元素,即:
<p>元素的点击事件先触发,然后会触发<div>元素的点击事件。 -
捕获 ,外部元素的事件会先被触发,然后才会触发内部元素的事件,即:
<div>元素的点击事件先触发 ,然后再触发<p>元素的点击事件。
捕获阶段很少使用,通常我们会在冒泡时处理事件。这背后有一个逻辑。
在现实世界中,当事故发生时,当地警方会首先做出反应。他们最了解发生这件事的地方。然后,如果需要,上级主管部门再进行处理。
事件处理程序也是如此。在特定元素上设置处理程序的代码,了解有关该元素最详尽的信息。特定于
<td>的处理程序可能恰好适合于该<td>,这个处理程序知道关于该元素的所有信息。所以该处理程序应该首先获得机会。
然后,它的直接父元素也了解相关上下文,但了解的内容会少一些,以此类推,直到处理一般性概念并运行最后一个处理程序的最顶部的元素为止。
参考资料:
Event dispatch and DOM event flow
🎨【点赞】【关注】不迷路,更多前端干货等你解锁
往期推荐