JavaScript 中的 window.onload 应该什么时候写
0. 参考资料
- 《JavaScript DOM 编程艺术》第 69 页
- JS中window.onload事件详解
- 为什么把 Script 标签放在 body 结束标签之后 html 结束标签之前?
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文件,并不能确定谁先下载完成。
- 因为脚本加载时文档可能不完整,所以模型也不完整。没有完整的
DOM,getElementsByTagName等方法就不能正常工作。
原文 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 likegetElementsByTagNamesimply 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