JavaScript 中的 window.onload 应该什么时候写

1,189 阅读3分钟

JavaScript 中的 window.onload 应该什么时候写


0. 参考资料


1. 页内式 JS 代码

1.1 页内式 JS 代码写在 head 内部

如果 script 标签写在 head 标签内部,则位于 body 内的元素将晚于 JS 代码加载,那么其中一些获取 DOM 元素的方法将无法取得元素(返回 null)。 以下示例代码的意图是把“我要红红火火恍恍惚惚!”这一段文字变成红色,可见并没有起作用,控制台也会报错。

示例代码:test1.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>写在页内且位于head中的JS代码</title>
    <script>
        document.getElementById("text").style.color = "red";
    </script>
</head>
<body>
    <p id="text">
        我要红红火火恍恍惚惚!
    </p>
</body>
</html>

效果及报错信息 效果及报错信息 修改代码,加上 window.onload

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>页内式JS代码写在head内部</title>
    <script>
        window.onload = function () {
            document.getElementById("text").style.color = "red";
        };
    </script>
</head>
<body>
    <p id="text">
        我要红红火火恍恍惚惚!
    </p>
</body>
</html>

最终显示效果 最终显示效果


1.2 页内式 JS 代码写在 body 结束之前

页内式 JS 代码写在 </body> 前面,则其它元素会早于 JS 代码加载,所以不用写 window.onload,当然加上也不影响什么。

示例代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>页内式JS代码写在body结束标签之前</title>
</head>
<body>
    <p id="text">
        我要红红火火恍恍惚惚!
    </p>
    <script>
        document.getElementById("text").style.color = "red";
    </script>
</body>
</html>

显示效果 显示效果


1.3 结论

对于页内式 JS 代码:

  • 如果 script 标签写在 head 标签内部,必须写 window.onload
  • 如果 script 标签写在 </body> 标签前面,不用写 window.onload

2. 外链式 JS 代码

结论:外链式 JS 代码,不管 script 标签写在哪里,都需要写 window.onload

  • 如果 script 标签写在了 head 标签内部,那么该 JS 代码会在 HTML 文档之前加载到浏览器。
  • 如果 script 标签写在了 </body> 前面,同样无法保证哪个文件最先结束加载,因为浏览器可能一次加载多个文件。

关于“一次加载多个文件”的个人理解:同时下载 html 文件和外链的 js 文件,并不能确定谁先下载完成。

  • 因为脚本加载时文档可能不完整,所以模型也不完整。没有完整的 DOMgetElementsByTagName 等方法就不能正常工作。

原文 This code will be executed as soon as the JavaScript file loads. If the JavaScript file is called from a <script> tag in the <head> of your document, the JavaScript file will load before the document. Likewise, if the <script> tag is at the bottom of the document before the </body> there’s still no guarantee which files will finish loading first (the browser may download more than one at a time). Because the document may be incomplete when the script loads, the model of the document is also incomplete, and methods like getElementsByTagName simply won’t work.


3. 杂谈

window.onload 为什么管用?

  • 文档对象 document 会被加载到一个浏览器窗口对象 window 里,文档对象 document 作为窗口对象 window 的一个属性存在。当窗口对象 window 触发加载完毕事件(onload)时,window.document 属性已经可以正常访问并使用。
  • 所以在 window.onload 指派的回调函数里面,文档对象 document 是完整的,于是在里面编写的 JavaScript 代码能够访问到完整的 DOM 树。

能不能把 script 标签写在 </body> 标签之后?

  • 最好不要把 script 标签写在 </body> 标签之后,这从 HTML 2.0 开始就是不合标准的。
  • 按照 HTML5 标准,如果在 </body> 后再出现 <script> 或任何元素的开始标签,都是 parse error,浏览器会忽略之前的 </body>,即视作仍旧在 body 内。所以实际效果和写在 </body> 之前是没有区别的。

完成于 2019.03.07 修订于 2019.08.25