事件冒泡是如何作用于事件处理的?

How does event bubbling work on event handling?

我已经定义了这个事件处理器:

document.addEventListener("load", function(){
  alert("Called on page load");
}, false);

我注意到当布尔标志设置为 false(在气泡阶段触发)时它不会被调用。谁能帮我看看为什么会这样。

当一个事件被发送到一个元素时,它会在捕获阶段沿着文档树下降,直到它到达目标。然后,如果它是冒泡事件,它会重新冒泡。

来自 2.1 Introduction to “DOM Events” in the DOM standard:

When an event is dispatched to an object that participates in a tree (e.g. an element), it can reach event listeners on that object’s ancestors too. First all object’s ancestor event listeners whose capture variable is set to true are invoked, in tree order. Second, object’s own event listeners are invoked. And finally, and only if event’s bubbles attribute value is true, object’s ancestor event listeners are invoked again, but now in reverse tree order.

load 不是冒泡事件,而且 - 这是重要的部分 - 它不针对 document。当您添加捕获侦听器时,您实际上是从通常接收事件的文档内容部分(如脚本或图像)获取 load 事件。在只有脚本的页面上,你根本看不到监听器被调用:

<iframe srcdoc="<script>document.addEventListener('load', () => { alert('loaded'); }, true);</script>"></iframe>

并且在包含 load 事件的页面上,事件在附加侦听器后触发,例如包含 <style>s 的 Stack Snippet,您会不止一次看到它:

let i = 0;

document.addEventListener('load', e => {
    console.log(`loaded ${++i}: ${e.target.nodeName}`);
}, true);

您可能打算向 window 添加一个 non-capturing 侦听器而不是 document,因为 window 是接收 load 事件的东西,不像document。 (或者您可能有其他意思。有很多方法可以解释“页面加载”。请参阅 Window: load event on MDN 以了解 load 事件在 window 上的含义的详细信息以及替代方案(如果不是) '如你所愿。)

window.addEventListener("load", function() {
    alert("Called on page load");
}, false);