加载事件不适用于 addEventListener 但适用于 onload 属性

load event doesn't work with addEventListener but works with onload property

const body = document.querySelector("body");

body.addEventListener("load", () => {
  console.log("test");
});

body.onload = () => {
  console.log("test");
};

当我只使用 addEventListener 时,我在控制台中看不到消息,但如果我使用 onload 属性 或在 html 中使用 onload 属性,它会起作用

这是因为 load 事件是所谓的 Window-reflecting body element event handler set 的一部分。
基本上,这些事件也可以作为 <body> 元素上的 HTML 属性和 IDL 属性访问,即使主要目标实际上是 Window 对象。

这样做是因为历史上我们必须使用 HTML 属性来设置事件处理程序,而在 <body> 标记中设置加载事件更为“自然”。从那时起,我们有了更好的方法来设置事件处理程序,我们可以清楚地定义此事件在 Window 对象上触发,这更符合逻辑。
然而浏览器仍然需要支持监听 onload="" HTML 属性的代码,所以这个反射的东西已经设置好了。
请注意,它不仅仅是添加一个新的事件侦听器,该事件实际上仅在 Window 对象上触发,但可以从 <body> 设置处理程序,甚至覆盖已在 [=13] 上设置的处理程序=]对象。

window.onmessage = (evt) => console.log("handled a message from Window, is Window the currentTarget:", evt.currentTarget === window);
document.body.onmessage = (evt) => console.log("handled a message from body, is Window the currentTarget:", evt.currentTarget === window);
postMessage("hello", "*");

EventTarget#addEventListener() 无法执行此重新定位,因此当您执行 document.body.addEventListener("load", cb) 时,您实际上是在等待将通过 <body> 元素的事件,但正如所演示的上面,事件实际上只在 Window 对象上触发。