javascript - 使用事件监听器向上冒泡或向下传播时,为什么我看不到多个 console.log() 操作?

标签 javascript addeventlistener

const containers = document.querySelectorAll('div.container');


containers.forEach(container => {
  container.addEventListener('click', e => {
    console.log('I am fired');
  }, true);
});

// containers.forEach(container => {
//   container.addEventListener('click', e => {
//     console.log('I am fired');
//   }, false);
// });
body {
  font-family: Lato;
}

.group {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

.container {
  background-color: #1f1f1f;
  color: #ccc;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 100px;
  width: 100px;
  margin: 0 30px;
  cursor: pointer;
}

.container h2 {
  margin: 0;
  margin-bottom: 5px;
}

span {
  font-size: 12px;
}
<div class="group">
  <div class="container" data-letter="A">
    <h2>A</h2>
    <span>Subtitle</span>
  </div>

  <div class="container" data-letter="B">
    <h2>B</h2>
    <span>Subtitle</span>
  </div>

  <div class="container" data-letter="C">
    <h2>C</h2>
    <span>Subtitle</span>
  </div>
</div>

无论我是向上冒泡还是向下传播,并将 console.log 消息放入事件处理程序中,console.log() 消息都只会触发一次。难道它不应该在每次遇到 DOM 树中的新元素时触发吗?

最佳答案

Regardless if I bubble up or propagate down and I put a console.log message in the event handler, the console.log() message is only ever fired once. Shouldn't it fire every time it hits a new element in the DOM tree?

您的 div.container 元素都不在任何其他元素内。捕获和传播发生在祖先/后代层次结构中,而不是在 sibling 或其他类似层次结构中发生。

如果将它们放在一起,您会看到多条消息:

const containers = document.querySelectorAll('div.container');


containers.forEach(container => {
  container.addEventListener('click', e => {
    console.log('I am fired');
  }, true);
});

// containers.forEach(container => {
//   container.addEventListener('click', e => {
//     console.log('I am fired');
//   }, false);
// });
body {
  font-family: Lato;
}

.group {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

.container {
  background-color: #1f1f1f;
  color: #ccc;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 100px;
  width: 100px;
  margin: 0 30px;
  cursor: pointer;
}

.container h2 {
  margin: 0;
  margin-bottom: 5px;
}

span {
  font-size: 12px;
}
<div class="group">
  <div class="container" data-letter="A">
    <h2>A</h2>
    <span>Subtitle</span>
    <div class="container" data-letter="B">
      <h2>B</h2>
      <span>Subtitle</span>
      <div class="container" data-letter="C">
        <h2>C</h2>
        <span>INNERMOST - click here</span>
      </div>
    </div>
  </div>
</div>

这是一个更简单的示例:

const phaseName = {
    [Event.NONE]: "NONE",
    [Event.CAPTURING_PHASE]: "CAPTURING_PHASE",
    [Event.AT_TARGET]: "AT_TARGET",
    [Event.BUBBLING_PHASE]: "BUBBLING_PHASE",
};
function handler(e) {
    console.log(`div#${this.id} - ${phaseName[e.eventPhase] || "(unknown)"}`);
}
document.querySelectorAll("#container div").forEach(el => {
    el.addEventListener("click", handler, true);
    el.addEventListener("click", handler, false);
});
<div id="container">
    <div id="a">
        <div id="b">
            <div id="c">
                Click here
            </div>
        </div>
    </div>
    <div id="d">
        <div id="e">
            <div id="f">
                Or here
            </div>
        </div>
    </div>
</div>

如果您点击“点击此处”,您会看到事件通过 #a#b 向下传播到 #c,然后冒泡再次起来。它不会通过 #d#e#f。如果您单击“或此处”,它将遍历这些内容,而不是 #a#b#c

详情请参阅DOM UI Events spec ,其中有 this section有了这个可爱的图表:

enter image description here

关于javascript - 使用事件监听器向上冒泡或向下传播时,为什么我看不到多个 console.log() 操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58612936/

相关文章:

javascript - 如何使用不同元素的事件监听器管理不同的事件?

javascript - 在自动完成表单上输入 onkeydown 功能

Javascript 调试 - addEventListeners - 点击事件陷入时间性能问题

javascript - 存储事件监听器在隐身或私有(private)窗口中无法正常工作

javascript - Openlayer 的 drawstart 事件在 drawend 发生后多次触发

javascript - 如何从 localStorage 中检索多个键和值

javascript - HTML 日期 : Get Correct date in yyyy - mm - dd

javascript - Google 循环脚本未运行

javascript - addEventListener 和 setInterval 在 Greasemonkey 脚本中静默失败

javascript - MongoDB:获取数组的计数