javascript - 为什么捕获阶段不会被 event.stopPropagation 打断?

标签 javascript event-handling dom-events stoppropagation event-propagation

如果运行此代码并单击 P,整个捕获阶段将执行,但冒泡阶段将按预期在 div 上停止。这段代码有什么问题?

  for(let elem of document.querySelectorAll('*')) {
    elem.addEventListener("click", e => alert(`Capturing: ${elem.tagName}`), true);
    elem.addEventListener("click", e => alert(`Bubbling: ${elem.tagName}`));
  }
<form>FORM
  <div onclick="event.stopPropagation()">DIV
    <p>P</p>
  </div>
</form>

最佳答案

捕获阶段不会中断,因为在现代浏览器中,事件默认在冒泡阶段注册(因此 onclick() 元素中的 <div> 事件不会与您在捕获阶段注册的单独事件处理程序交互).

我不知道通过 html 属性注册捕获阶段事件处理程序的方法(除了在某些较旧的浏览器中,在捕获阶段默认注册事件)。

请参阅下面的代码片段,了解您的代码的修改版本,我认为这可能是您最初的意图。您将看到此代码调用 stopPropagation()在捕获阶段和冒泡阶段处理程序中(在这两种情况下都会产生预期的结果)。

for (const elem of document.querySelectorAll('*')) {
  elem.addEventListener('click', (event) => {
    if (elem.tagName === 'DIV') {
      event.stopPropagation();
    }
    
    console.log(`Capturing: ${elem.tagName}`);
  }, true);
  
  elem.addEventListener('click', (event) => {
    if (elem.tagName === 'DIV') {
      event.stopPropagation();
    }
    
    console.log(`Bubbling: ${elem.tagName}`);
  });
}
<form>
  form
  <div>
    div (click here)
    <p>p</p>
  </div>
</form>

在捕获阶段,浏览器从最外层父节点开始处理处理程序,因此不会遇到stopPropagation()。直到它已经处理了 click所有父元素的处理程序 <html> , <body>

在冒泡阶段,它处理事件处理程序,从被点击的元素开始向外移动到父元素。

关于javascript - 为什么捕获阶段不会被 event.stopPropagation 打断?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54312521/

相关文章:

javascript - 在jQuery插件成员中正确获取 "this"

multithreading - GTK 和 nanomsg 的线程友好主循环

javascript - 如何从另一个范围内的函数调用事件监听器?

javascript - 如何获取表中当前元素之前出现的具有特定类的元素数?

javascript - 转换日期格式

javascript - 带有可选路径参数的 react 路由器

javascript - Wijmo 的 valueChanged 事件 + Angular 2 上的数据绑定(bind)问题

Spring @EventListener 注释不起作用

javascript - 单击汉堡菜单后看不到我的文字

javascript - 使用 "input"事件动态更改背景颜色