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