window.onload 与 document.onload

Posted

技术标签:

【中文标题】window.onload 与 document.onload【英文标题】:window.onload vs document.onload 【发布时间】:2010-10-09 22:30:12 【问题描述】:

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

【问题讨论】:

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 即便如此,在今天的 Firefox 75.0 中,window.onloaddocument.onload 彼此不同 window.onload 似乎之后发生,并且比document.onload 加载更多! (有些事情正在使用的窗口不能使用文档!这也适用于 document.onreadstatechange 'complete'!) 【参考方案1】:

他们什么时候开火?

window.onload

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

在某些浏览器中,它现在接管了document.onload 的角色,并在 DOM 准备就绪时触发。

document.onload

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

它们的支持情况如何?

window.onload 似乎是最广泛支持的。事实上,一些最现代的浏览器在某种意义上已经将document.onload 替换为window.onload

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

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

出于历史的目的。 window.onloadbody.onload

有一段时间在codingforums 上提出了类似的问题 关于window.onload 的使用超过body.onload。这 结果似乎是你应该使用window.onload,因为它是 很好地将您的结构与动作分开。

【讨论】:

实际上,该声明似乎针对window.onload<body onload=""> 之间的选择,这是完全不同的(在这种情况下,“将结构与操作分开”更有意义)。不是答案错了,而是其依据是错的。 那句话在语法上很糟糕......不应该有一些(标记的)编辑帮助吗? @Thor84no 我终于有时间再看看这个。我做了一些改进。 @Kheldar 我决定改写这句话,因为它相当粗略。 @JoshMein 是否意味着document.onload 是 jQuery document.ready 的 JS 等价物?【参考方案2】:

一般的想法是window.onload 触发,当文档的窗口准备好展示document.onload 触发,当DOM 树(由文档中的标记代码构建)完成

理想情况下,订阅 DOM-tree events,允许通过 javascript 进行屏幕外操作,几乎没有 CPU 负载。相反,当尚未请求、解析和加载多个外部资源时,window.onload 可能需要一段时间才能触发

►测试场景:

要观察差异以及您的浏览器选择实现上述事件处理程序的方式,只需在您的文档中插入以下代码 - @ 987654325@- 标记。

<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&lt;body&gt; 内声明时会触发两次,在 &lt;head&gt; 内声明时会触发一次(然后事件充当 document.onload )。 根据计数器的状态进行计数和操作允许模拟这两种事件行为。 或者在 html-&lt;head&gt; 元素的范围内声明 window.onload 事件处理程序。

►示例项目:

以上代码取自this project's 代码库(index.htmlkeyboarder.js)。


有关event handlers of the window object 的列表,请参阅 MDN 文档。

【讨论】:

【参考方案3】:

添加事件监听器

<script type="text/javascript">
  document.addEventListener("DOMContentLoaded", function(event) 
      /* 
        - Code to execute when only the HTML document is loaded.
        - This doesn't wait for stylesheets, 
          images, and subframes to finish loading. 
      */
  );
</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')
)

祝你好运。

【讨论】:

"当初始 HTML 文档完全加载和解析时触发 DOMContentLoaded 事件,无需等待样式表、图像和子框架完成加载。" - developer.mozilla.org/en/docs/Web/Events/DOMContentLoaded 所以你似乎对这次活动中加载的所有内容都不正确。 @ProfK,感谢您的反馈。你可以试试window.addEventListener('load', function() ...)。我也更新了我的答案。 我喜欢这个答案的地方是它提供了一个普通的旧javascript解决方案。你会认为大多数人认为 jQuery 是内置在所有浏览器中的,因为它是作为唯一答案给出的频率。 当该死的 jquery 加载时间过长并且您找不到 $ 时,双重问题。我认为 $(window).ready 类型的解决方案永远不应该被信任工作。 我在今天的 chrome 中都试过了。它不等待 css 和字体。【参考方案4】:

根据Parsing HTML documents - The end,

    浏览器解析 HTML 源代码并运行延迟脚本。

    当所有 HTML 都已解析并运行时,DOMContentLoaded 将在 document 处调度。事件冒泡到window

    浏览器加载资源(如图片)会延迟加载事件。

    load 事件在 window 处调度。

因此,执行顺序将是

    捕获阶段windowDOMContentLoaded 事件监听器 DOMContentLoadeddocument 的事件监听器 处于冒泡阶段的windowDOMContentLoaded 事件监听器 windowload 事件监听器(包括onload 事件处理程序)

不应调用document 中的气泡load 事件侦听器(包括onload 事件处理程序)。 仅捕获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
;

【讨论】:

我运行了你的 sn-p 并且 document - load - capture 确实发生了,这与我在搜索中所期望的关于为什么我没有发生文档加载的预期相反。奇怪的是,它是不一致的。有时会出现,有时不会,有时会出现两次 - 但从来没有发生过document - load - bubble。我建议不要使用document load @erroric 好点。我不认为load 事件是在外部资源上调度的。该事件不会冒泡,因此通常不会在文档中检测到,但应该在捕获阶段。这些条目是指&lt;style&gt;&lt;script&gt; 元素的负载。我认为 Edge 适合展示它们,而 Firefox 和 Chrome 是错误的。 感谢 Oriol,useCapture 选项教会了我一些新东西。 感谢您总结 w3 的解析和渲染流程。我只是想知道在第 4 步之后一旦“加载”事件被触发,还会发生什么?我注意到在我的浏览器上,有时在加载事件触发后仍然会获取一些对象,尽管我根本没有触摸或与页面交互。你知道这些物体叫什么吗? ‘非阻塞渲染对象?【参考方案5】:

在 Chrome 中,window.onload 与 &lt;body onload=""&gt; 不同,而在 Firefox(35.0 版)和 IE(11 版)中它们是相同的。

您可以通过以下 sn-p 进行探索:

<!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”。如果你在IE&FF的控制台运行“window.onload.toString()”,你会看到:

"函数加载(事件) bodyOnloadHandler() "

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

【讨论】:

【参考方案6】:

window.onloadonunloaddocument.body.onloaddocument.body.onunload 的快捷方式

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

'onload' 在文档中 -> true

【讨论】:

【参考方案7】:

总之

window.onload 是 not supported by IE 6-8 任何现代浏览器都不支持document.onload(从不触发事件)

window.onload   = () => console.log('window.onload works');   // fired
document.onload = () => console.log('document.onload works'); // not fired

【讨论】:

s/windows/window【参考方案8】:

window.onload 但是它们通常是同一个东西。同样body.onload在IE中变成window.onload。

【讨论】:

【参考方案9】:

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

【讨论】:

【参考方案10】:

document.load 未定义。那你们在说什么?

document.addEventListener('load',cbFunc) 的事件,cbFunc 永远不会被触发。

【讨论】:

以上是关于window.onload 与 document.onload的主要内容,如果未能解决你的问题,请参考以下文章

jquery $(document).ready() 与window.onload的区别

jquery $(document).ready() 与window.onload的区别

window.onload与$(document).ready() 的区别

jquery $(document).ready() 与window.onload的区别

window.onload与$(document).ready()的对比

jquery $(document).ready() 与window.onload的区别