window.onload与document.onload


709

哪个受到更广泛的支持:window.onloaddocument.onload


2
MDN文档解释了以下window事件: onloadDOMContentLoaded。用法示例:,window.addEventListener('DOMContentLoaded', callback)。截至2019年中,与所有主流浏览器兼容。----- developer.mozilla.org/en-US/docs/Web/API/Window/... ------ developer.mozilla.org/en-US/docs/Web/API/Window/load_event
Craig Hicks

对我来说甚至还在,今天在Firefox 75.0,window.onload并且document.onload不同的对方! window.onload似乎是之后发生的,负载比document.onload!(某些事情正在使用与文档不兼容的窗口!这也适用于document.onreadstatechange'完成'!)
安德鲁

Answers:


722

他们什么时候开火?

window.onload

  • 默认情况下,会在加载整个页面(包括其内容(图像,CSS,脚本等))时触发。

在某些浏览器中,它现在document.onload也可以充当DOM 的角色并在DOM准备就绪时触发。

document.onload

  • 当DOM准备就绪时可以调用它,可以加载图像和其他外部内容之前

他们的支持程度如何?

window.onload似乎得到了最广泛的支持。实际上,从某种意义上讲,某些最现代的浏览器已替换document.onloadwindow.onload

浏览器支持问题很可能是许多人开始使用jQuery之类的库来处理对文档准备就绪的检查的原因,如下所示:

$(document).ready(function() { /* code here */ });
$(function() { /* code here */ });

为了历史的目的。window.onloadvs body.onload

不久前codingforums上也提出了类似的问题,涉及window.onloadover 的用法body.onload。结果似乎是您应该使用,window.onload因为将您的结构与操作分开是很好的。


25
实际上,该陈述似乎是针对两者之间的选择,window.onload<body onload="">这是完全不同的(在这种情况下,“从动作中分离结构”更加有意义)。答案不是错误的,而是依据。
Thor84no 2012年

2
那句话在语法上太可怕了……某些(标记)的编辑帮助不应该吗?
希尔德

@ Thor84no我终于找到了时间再看一遍。我做了一些改进。
Josh Mein 2013年

@Kheldar我决定对报价进行解释,因为它很粗糙。
Josh Mein 2013年

@JoshMein这是否意味着document.onloadjQuery等同于JS document.ready
约翰cj

276

总的想法是,在window.onload火灾时文档的窗口准备演示document.onload火灾的时候DOM树(文档内的标记代码生成)的完成

理想情况下,订阅DOM树事件,可以通过Javascript进行屏幕外操作,几乎不占用CPU负载。相反,当尚未请求,解析和加载多个外部资源时,window.onload可能要花一些时间

►测试场景:

要观察差异以及选择的浏览器如何实现上述事件处理程序,只需将以下代码插入文档的<body>--标记中。

<script language="javascript">
window.tdiff = []; fred = function(a,b){return a-b;};
window.document.onload = function(e){ 
    console.log("document.onload", e, Date.now() ,window.tdiff,  
    (window.tdiff[0] = Date.now()) && window.tdiff.reduce(fred) ); 
}
window.onload = function(e){ 
    console.log("window.onload", e, Date.now() ,window.tdiff, 
    (window.tdiff[1] = Date.now()) && window.tdiff.reduce(fred) ); 
}
</script>

►结果:

这是由此产生的行为,对于Chrome v20(可能是大多数当前的浏览器)而言,是可观察到的。

  • 没有document.onload事件。
  • onload在中声明时触发两次,在中声明时触发<body>一次<head>(事件在此充当document.onload)。
  • 根据计数器的状态进行计数和操作可以模拟两种事件行为。
  • 或者window.onload,在HTML- <head>元素的范围内声明事件处理程序。

►示例项目:

上面的代码摘自该项目的代码库(index.htmlkeyboarder.js)。


有关window对象事件处理程序的列表,请参考MDN文档。


141

添加事件监听器

<script type="text/javascript">
  document.addEventListener("DOMContentLoaded", function(event) {
      // - Code to execute when all DOM content is loaded. 
      // - including fonts, images, etc.
  });
</script>


Update March 2017

1个香草JavaScript

window.addEventListener('load', function() {
    console.log('All assets are loaded')
})


2个jQuery

$(window).on('load', function() {
    console.log('All assets are loaded')
})


祝好运。


14
“当初始HTML文档已完全加载并解析时,无需等待样式表,图像和子帧完成加载,就会触发DOMContentLoaded事件。” - developer.mozilla.org/en/docs/Web/Events/DOMContentLoaded所以,你似乎是不正确的事情了,在这种情况下被加载。
ProfK

2
@ProfK,谢谢您的反馈。你能试一下吗window.addEventListener('load', function() {...})。我也更新了答案。
Akash

4
我喜欢这个答案,因为它提供了一个纯老式的javascript解决方案。您可能会认为,大多数人认为jQuery是内置在所有浏览器中的,因为它是唯一的答案。
戴夫·兰德

当该死的jquery加载时间太长而您找不到$时,出现双重问题。我认为永远不要信任$(window).ready类型的解决方案。
Shayne

1
我在今天的Chrome浏览器中都尝试过。它不是在等待CSS和字体。
movAX13h

78

根据解析HTML文档-最后

  1. 浏览器解析HTML源并运行延迟的脚本。

  2. 在所有HTML都已解析并运行DOMContentLoaded后,document在调度A。事件冒泡到window

  3. 浏览器加载延迟加载事件的资源(如图像)。

  4. load调度了一个事件window

因此,执行顺序为

  1. DOMContentLoadedwindow捕获阶段的事件侦听器
  2. DOMContentLoaded 的事件监听器 document
  3. DOMContentLoadedwindow泡沫阶段的事件侦听器
  4. load的事件监听器(包括onload事件处理程序)window

切勿调用load其中的冒泡事件侦听器(包括onload事件处理程序)document只能load调用捕获侦听器,但这是由于诸如样式表之类的子资源的负载,而不是由于文档本身的负载。

window.addEventListener('DOMContentLoaded', function() {
  console.log('window - DOMContentLoaded - capture'); // 1st
}, true);
document.addEventListener('DOMContentLoaded', function() {
  console.log('document - DOMContentLoaded - capture'); // 2nd
}, true);
document.addEventListener('DOMContentLoaded', function() {
  console.log('document - DOMContentLoaded - bubble'); // 2nd
});
window.addEventListener('DOMContentLoaded', function() {
  console.log('window - DOMContentLoaded - bubble'); // 3rd
});

window.addEventListener('load', function() {
  console.log('window - load - capture'); // 4th
}, true);
document.addEventListener('load', function(e) {
  /* Filter out load events not related to the document */
  if(['style','script'].indexOf(e.target.tagName.toLowerCase()) < 0)
    console.log('document - load - capture'); // DOES NOT HAPPEN
}, true);
document.addEventListener('load', function() {
  console.log('document - load - bubble'); // DOES NOT HAPPEN
});
window.addEventListener('load', function() {
  console.log('window - load - bubble'); // 4th
});

window.onload = function() {
  console.log('window - onload'); // 4th
};
document.onload = function() {
  console.log('document - onload'); // DOES NOT HAPPEN
};


我运行了您的代码片段,document - load - capture并确实发生了这,这与我在搜索中期望的为什么文档加载没有发生的原因背道而驰。奇怪的是,这是不一致的。有时它出现,有时它没有出现,有时它出现两次-但从未document - load - bubble发生。我建议不要使用document load
错误

@erroric好点。我不认为load事件是在外部资源上调度的。该事件不会冒泡,因此通常不会在文档上检测到它,但是应该在捕获阶段。这些条目引用<style><script>元素的负载。我认为Edge是展示它们的正确方法,而Firefox和Chrome是错误的。
Oriol

感谢Oriol,该useCapture选项教会了我一些新知识。
Paul Watson

感谢您总结来自w3的解析和渲染流程。我只是想知道在步骤4之后,一旦触发“加载”事件,还会发生什么?我在浏览器中注意到,有时即使未触摸页面也未与页面进行交互,但在加载事件触发后有时仍会提取某些对象。您知道那些对象叫什么吗?'不阻塞渲染对象?
weefwefwqg3

12

在Chrome中,window.onload与 <body onload="">,而Firefox(版本35.0)和IE(版本11)都相同。

您可以通过以下代码段进行探索:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <!--import css here-->
        <!--import js scripts here-->

        <script language="javascript">

            function bodyOnloadHandler() {
                console.log("body onload");
            }

            window.onload = function(e) {
                console.log("window loaded");
            };
        </script>
    </head>

    <body onload="bodyOnloadHandler()">

        Page contents go here.

    </body>
</html>

在Chrome控制台中,您会同时看到“窗口加载”(首先出现)和“主体加载”。但是,您将在Firefox和IE中看到“ body onload”。如果您运行“window.onload.toString()在IE&FF的控制台中 ”,则会看到:

“函数onload(event){bodyOnloadHandler()}”

这意味着赋值“ window.onload = function(e)...”被覆盖。


6

window.onloadonunload有快捷键document.body.onloaddocument.body.onunload

document.onloadonload所有html标签上的处理程序似乎已保留,但从未触发

' onload'在文档中-> true


5

window.onload但是,它们通常是同一回事。同样,body.onload在IE中成为window.onload。


1

Window.onload是标准,但是-PS3(基于Netfront)中的Web浏览器不支持window对象,因此您不能在那里使用它。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.