简体   繁体   English

加载事件不适用于 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");
};

when i use only addEventListener i don't see the message in the console but if i use onload property or use onload attribute in the html it works当我只使用 addEventListener 时,我在控制台中看不到消息,但是如果我使用 onload 属性或在 html 中使用 onload 属性,它就可以工作

This is because the load event is part of what is called the Window-reflecting body element event handler set .这是因为load事件是所谓的Window-reflecting body element event handler set的一部分。
Basically, these events are also accessible as HTML attributes and IDL attributes on the <body> element, even though the primary target is actually the Window object.基本上,这些事件也可以作为<body>元素上的 HTML 属性和 IDL 属性访问,即使主要目标实际上是Window object。

This is done because historically we had to use HTML attributes to set event handlers, and setting the load event in the <body> tag was more "natural".这样做是因为历史上我们必须使用 HTML 属性来设置事件处理程序,而在<body>标记中设置加载事件更加“自然”。 Since then we have gotten far better ways to set up event handlers and we can define clearly that this event fires on the Window object, which is more logical.从那时起,我们有了更好的方法来设置事件处理程序,我们可以清楚地定义这个事件在Window object 上触发,这更符合逻辑。
However browsers still need to support code that was listening to the onload="" HTML attribute, so this reflection thing has been set up.然而浏览器仍然需要支持监听onload="" HTML 属性的代码,所以这个反射的东西已经设置好了。
Note that it's not just adding a new event listener, the event actually only fires on the Window object, but the handler can be set from the <body> , even overriding the ones already set on the Window object.请注意,它不仅仅是添加一个新的事件侦听器,该事件实际上仅在Window object 上触发,但可以从<body>设置处理程序,甚至覆盖已在Window object 上设置的处理程序。

 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() has no means to do this retargetting, so when you do document.body.addEventListener("load", cb) , you are really waiting for an event that will go through the <body> element, but as demonstrated above, the event actually only fires on the Window object. EventTarget#addEventListener()没有办法进行这种重新定位,所以当您执行document.body.addEventListener("load", cb)时,您实际上是在等待一个将通过<body>元素 go 的事件,但正如所演示的上面,事件实际上只在Window object 上触发。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM