window.onload 与 document.onload

IT技术 javascript event-handling dom-events
2021-01-08 22:55:22

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

6个回答

他们什么时候开火?

window.onload

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

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

document.onload

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

他们的支持情况如何?

window.onload似乎是最广泛支持的。事实上,一些最现代的浏览器都在某种意义上取代document.onloadwindow.onload

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

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

为了历史的目的。window.onload对比body.onload

不久前codingforums有人问一个关于window.onloadover使用的类似问题body.onload结果似乎是您应该使用,window.onload因为将您的结构与动作分开是很好的。

@Thor84no 我终于有时间再看看这个。我做了一些改进。
2021-03-16 22:55:22
@Kheldar 我决定转述这句话,因为它相当粗糙。
2021-03-27 22:55:22
@JoshMein 这是否意味着document.onloadJS 等效于 jQuery document.ready
2021-04-01 22:55:22
其实这种说法似乎在之间进行选择,以定向window.onload<body onload="">这是完全不同的(和“从动作独立结构”使得在这方面有更多的意义上)。不是答案是错误的,而是它的基础是错误的。
2021-04-03 22:55:22
这句话在语法上很糟糕……一些(标记的)编辑不应该有帮助吗?
2021-04-07 22:55:22

一般的想法是window.onload在文档的窗口准备好呈现触发document.onloadDOM 树(从文档中的标记代码构建)完成触发

理想情况下,订阅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 文档。

添加事件监听器

<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')
})

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

根据解析 HTML 文档 - 结束

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

  2. A在所有 HTML 都已解析并运行后DOMContentLoaded分派document事件冒泡到window

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

  4. load分派一个事件window

因此,执行顺序将是

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

永远不应该调用气泡load事件侦听器(包括onload事件处理程序)documentload可能只调用捕获侦听器,但由于像样式表这样的子资源的负载,而不是由于文档本身的负载。

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
};

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

在 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)...”被覆盖。