何时使用"window.onload"?

63
在JavaScript中,当我想在页面加载完成后运行脚本时,我应该使用window.onload还是直接编写脚本?
例如,如果我想要一个弹出窗口,我应该写(直接在<script>标签内):
alert("hello!");
或者:
window.onload = function() {
    alert("hello!");
}

两者似乎都在页面加载后立即运行。它们的区别是什么?

7个回答

85

其他答案似乎都已过时。

首先,将脚本放在顶部并使用window.onload是一种反模式。最多只能算是IE时代的剩余物,或者最坏情况下是对JavaScript和浏览器的误解。

你可以将你的脚本移到html底部。

<html>
  <head>
   <title>My Page</title>
  </head> 
  <body>
    content

    <script src="some-external.js"></script>
    <script>
      some in page code
    </script>
  </body>
</html>

人们唯一使用window.onload的原因是因为他们错误地认为脚本需要放在head部分。由于按顺序执行,如果您的脚本位于头部,则通过“按顺序执行”的定义,正文和内容尚不存在。

简单粗暴的解决方法是使用window.onload等待页面的其余部分加载。将脚本移动到底部也解决了这个问题,现在不需要使用window.onload,因为您的正文和内容已经被加载。

更现代的解决方案是在脚本上使用defer标签,但要使用它,您的脚本需要全部外部化。

<head>
    <script src="some-external.js" defer></script>
    <script src="some-other-external.js" defer></script>
</head>

这样做的优点是浏览器将立即开始下载脚本并按指定顺序执行它们,但它将在页面加载后才执行它们,无需使用window.onload或更好的但仍然不需要的window.addEventListener('load', ...


1
哇,这个问题很老啊!谢谢你提供 defer 的提示。我之前看到过它,但从没意识到它的含义。 - Jonathan Lam
5
是的,这是在谷歌搜索“何时使用'window.onload'”时的第一个结果,因此似乎需要一个更新的答案。 - gman
为什么window.addEventListener更好?你认为像window.onload一样,人们使用window.addEventListener('load',...)的唯一原因是因为他们不知道可以将脚本放在body的末尾吗? - barlop
addEventListener比onload更好,因为多个脚本可以使用它。只有一个脚本可以使用onload。defer是最好的选择,但旧浏览器不支持它。因此,您可以在addEventListener中使用defer,在新浏览器中加载速度最快,但仍然可以在旧浏览器中加载。 - gman
1
让我补充一下,即使页面已经完成加载,包括加载图像和iframe,负载仍然在运行。如果这对您的脚本很重要,那么也许您想使用负载事件。大多数脚本都希望开始执行他们计划做的事情,而不必等待图像和iframe完成。 - gman
显示剩余5条评论

57

window.onload 只有当浏览器到达它时才会运行。

window.addEventListener 等待窗口加载完成后再运行。

一般来说,您应该使用第二种方式,但是应该附加一个事件监听器而不是定义一个函数。例如:

window.addEventListener('load', 
  function() { 
    alert('hello!');
  }, false);

8
这里是关于MDN文档的说明
根据文档:
加载事件会在文档加载过程结束时触发。此时,文档中的所有对象都在DOM中,所有图像和子框架都已完成加载。
您的第一段代码将在浏览器命中HTML的此处立即运行。
第二段代码将在DOM和所有图像完全加载后触发弹出窗口(请参见规范)。
考虑到alert()函数,它运行的时间并不重要(它除了window对象之外不依赖任何内容)。但是,如果您想操作DOM - 您应该等待它正确加载。

@xgqfrms jQuery 不是总是答案... - Jonathan Lam

3

你有三种选择:

  1. 直接在脚本标签内运行,一旦解析完成就会立即运行。

  2. document.addEventListener( "DOMContentLoaded", function(){}); 内部运行,将在 DOM 准备就绪后运行。

  3. window.onload function(){}) 内部运行,将在所有页面资源加载完毕后立即运行。


2
这取决于你想让它在脚本元素遇到时运行还是想让它在加载事件触发时运行(这是在整个文档(包括图像等)加载后发生的)。但两者都不总是正确的。一般来说,我会避免直接将函数分配给 onload ,而是使用 addEventListener (如果需要支持旧浏览器,则使用兼容性库)。

“一般来说,我会避免直接将函数分配给onload,而是使用addEventListener。为什么呢?” - barlop

2
等待DOM加载的原因是为了能够定位在脚本后加载的任何元素。如果你只是创建一个alert,那么这并不重要。但是,假设你要定位一个在脚本后标记中的div,如果你不等到DOM树中该部分加载完成,就会出现错误。
如果你使用jQuery,document.ready是一个很好的替代window.onload的选择。
请参见此处:window.onload vs $(document).ready()

2
另一个有趣的区别是,window.onload 只会被调用一次,并且它将覆盖先前附加的 onload 事件。但如果您使用 window.addEventListener,则可以添加任意数量的函数,多个 window.addEventListener 不会互相覆盖。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接