简述JavaScript的事件捕获和事件冒泡

创建JavaScript事件气泡是为了捕获和处理在DOM中传播的事件。
但你知道事件泡沫和事件捕获之间的区别吗?

在本文中,我将使用相关示例讨论您需要了解的有关此主题的所有内容。

事件流传播

在介绍事件收集和事件冒泡之前,我们首先看看如何在DOM中进一步传播事件。

如果有多个嵌套元素处理同一事件,我们会很困惑哪个事件处理程序将首先触发。
此时,有必要了解事件传播的顺序。

通常,事件会从父元素传播到目标元素,然后再传播回父元素。

JavaScript事件分为三个阶段:

捕获阶段:事件从父元素传播到目标元素并从Window对象传播。

目标阶段:事件到达目标元素或启动事件的元素。

冒泡阶段:此时,与捕获阶段相反,事件传播到父元素直至Window对象。

下图将帮助您更好地理解事件传播的生命周期:

现在您已经有了一个基本的了解了解了DOM事件流的内部原理之后,我们来看看事件捕获和冒泡过程是如何发生的。

什么是事件捕获

事件捕获是事件传播的初始场景,从数据包元素开始,到开始事件生命周期的目标元素结束。

如果您有一个事件绑定到浏览器的Window对象,则该事件将是第一个执行的事件。
因此,在下面的示例中,事件处理的顺序将是“窗口”、“文档”、“DIV2”、“DIV1”,最后是“按钮”。

这里我们可以看到事件捕获只发生在被点击的元素或目标上,事件不会传递给子元素。

我们可以使用addEventListener()方法的useCapture参数来订阅捕获阶段的事件。

target.addEventListener(type,listener,useCapture)

您可以使用下面的代码来测试上面的示例,获得事件捕获的实际体验。

window.addEventListener("click",()=>{console.log('窗口');},true);document.addEventListener("click",()=>{console.log('文档');},true);document.querySelector(".div2").addEventListener("click",()=>{console.log('DIV2');},true);document.querySelector(".div1").addEventListener("click",()=>{console.log('DIV1');},true);document.querySelector("按钮").addEventListener("click",()=>{console.log('CLICKME!');},true);什么是事件气泡

如果你知道如何捕获事件,那么创建事件气泡就非常简单了很容易理解就完成了与掌握事实恰恰相反。

事件冒泡将从子元素开始,并在DOM树中向上传播,直到处理顶部父元素的事件。

遗漏或者在addEventListener()中将useCapture参数设置为false将在冒泡阶段订阅事件。
因此,事件处理程序将默认侦听冒泡事件。

在我们的示例中,我们对所有事件使用事件集合或事件冒泡。
但是如果我们想在两个阶段处理事件怎么办?

举个例子,Document和DIV2点击事件在冒泡阶段处理,其他事件在收集阶段处理。

捕获时会分别触发连接到Window、DIV1和按钮的点击事件,而DIV2监听器和Document则处于沸腾状态。
按顺序激活。

window.addEventListener("click",()=>{console.log('Window');},true);document.addEventListener("click",()=>{console.log('文档');});//注册为冒泡document.querySelector(".div2").addEventListener("click",()=>{console.log('DIV2');});//发布签名为冒泡document.querySelector(".div1").addEventListener("click",()=>{console.log('DIV1');},true);document.querySelector("button").click",()=>{console.log('CLICKME!');},true);

我想现在您对事件流、事件冒泡和捕获事件有了清晰的了解。
苏。
那么,让我们看看什么时候可以使用事件集合和事件集合

事件集合和集合应用

通​​常,我们只需要在全局范围内执行一个函数来消费事件即可。
例如,我们可以注册一个文档范围的侦听器,如果DOM中发生事件,该侦听器将运行

同样,我们可以使用事件日志记录并创建Bubble来更改用户界面。

假设我们有一个允许用户选择单元格的表格,我们需要向用户显示所选的单元格

在这种情况下,为每个单元指定事件处理程序并不是一个好的做法,并且最终会导致代码重复。

是我们可以使用的解决方案。
通过冒泡和捕获事件来处理这些事件

因此,我为表格创建了一个单独的事件处理程序,用于更改单元格的样式

d。
ocument.querySelector("table").addEventListener("click",(event)=>{if(event.target.nodeName=='TD')event.target.style.background="rgb(230,226,40)";});

在事件处理程序中,我使用nodeName来匹配被单击的单元格,如果匹配,单元格的颜色就会改变

如何防止事件传播

双当事件冒泡并开始捕获时。
在我们的控制范围之外传播是很烦人的

如果您有过度嵌套的元素结构,这也会导致性能问题,因为每个事件都会生成一个新的事件循环。

在上面的情况下,当我单击删除按钮时,包装元素的单击事件也会被触发。
气泡引起的事件风险

我们可以通过以下方式避免这种行为使用stopPropagation()方法,这将阻止事件在DOM

树中向上或向下传播。
document.querySelector(".card").addEventListener("click",()=>{$("#detailsModal").modal();});document.querySelector("button").addEventListener("点击",(event)=>{event.stopPropagation();//停止冒泡$("#deleteModal").modal();});

文章摘要off

JavaScript事件收集和冒泡可用于高效处理Web应用程序中的事件。
了解事件流以及它如何收集和冒泡的工作原理将帮助您通过正确的事件处理来优化您的应用程序。

例如,如果您的应用程序中启动了任何意外事件,了解事件收集和冒泡可以节省您解决问题的时间。

所以我希望你尝试上面的例子,并在评论部分分享你的经验。

感谢您的阅读!

原文地址:EventBubblingandCapturinginJavaScript

原作者:DulankaKarunasena

翻译自:NuggetsTranslationProject

本文永久链接:

javascript中什么是冒泡

事件冒泡:事件按照从最具体的事件目标到最不具体的事件目标(文档对象)的顺序触发,即先触发子元素,后触发父元素。
假设有一个元素div,它有一个子元素p。

Element

两个元素都有与其关联的点击事件。
如果用户点击p,就会触发div和p上的点击事件。
p首先被触发,然后是div。
这称为事件冒泡。