事件侦听器捕获和冒泡阶段事件

Event Listener Capture and Bubbling Phase Events

本文关键字:事件 段事件 侦听器      更新时间:2023-09-26

在阅读了许多关于SO的教程和帖子后,我在脑海中有了这个问题一段时间,没有人能够给我提供克服这个障碍所需的心理模型。

这是一篇关于浏览器事件的精彩博客文章的节选:

当我们单击锚标记时,DOM计算捕获阶段路径,触发所有根文档、主体、div和锚标记的捕获阶段事件处理程序(按此顺序),然后它转过来并以与捕获阶段相反的顺序触发所有 Bubble Phase事件处理程序。

下面是引号中描述的代码片段:

<html>
  <head>
  </head>
  <body>
    <div id="myDiv">
      <a id="myAnchor" 
         href="http://bitovi.com/">bitovi!
      </a>
    </div>
  </body>
</html>
这是我不明白的地方。许多解释都将Capture和Bubble阶段描述为在DOM中上下移动,我理解这一点。我不明白"所有"事件是如何在捕获阶段沿着树向下走时被触发的,然后所有的气泡事件都被沿着树向上触发。"所有"指的是什么?是页面上的所有事件吗?它们是"默默地"触发的,因为它们不是实际的单击事件发生的地方,它们不执行,实际触发的唯一事件是被单击的元素,其余的事件只是出于某种原因存储?

在后面的博文中,另一种解释也让我感到困惑,这与我对"所有事件"的误解有关:

这描述了在捕获阶段事件执行期间发生的事情:

现在,循环遍历刚刚收集的所有元素(和翻转了)。这里我们需要做一些事情:

  • 我们需要检查event. stoppropagation()是否被触发的事件处理程序之一调用(参见项目列表的最后一步)。如果它是不是,跳出这个循环,我们不需要遍历

  • 接下来,我们检查是否为当前正在评估的DOM节点设置了任何Capture Phase事件处理程序。

  • 最后,循环遍历我们收集的所有处理程序,并在当前正在评估的节点上下文中执行它们。

我被最后两个要点弄糊涂了。"检查当前正在评估的DOM节点是否设置了捕获阶段事件处理程序"。我通常理解如何使用addEventListener方法设置事件处理程序。这里是混淆的地方:

"循环收集的所有处理程序,并在当前正在评估的节点上下文中执行它们"。

是否收集并执行页面上的所有处理程序?如果事件有停止。事件触发的dom节点上没有设置Prop事件或did,事件不会触发吗?

如果这个问题让你感到困惑,我很抱歉,我会尽力澄清任何不合理的地方。谢谢!

不是所有的事件,而是所有的事件处理程序¹。描述中只触发了一个事件,一个点击事件。该事件被传递到附加到捕获/气泡链中标识的元素的每个事件侦听器,除非它被stopPropagation()(或stopImmediatePropagation())阻止。

¹学究地说,它们是事件侦听器。事件处理程序"充当指定它们的对象的非捕获事件侦听器"。