JavaScript onload 事件:在页面加载完成后执行代码
写前端代码的时候,经常遇到一个问题:脚本在页面元素还没渲染出来的时候就执行了,结果找不到元素,报错。比如把 <script> 放在 <head> 里,直接去操作页面下方的 <div>,就会提示 null 或 undefined。
解决这个问题的一个方法,就是把代码放到 onload 事件里。onload 事件会在页面所有资源——包括 HTML 结构、图片、样式表、外部脚本——都加载完成后才触发。这相当于给代码加了一个“等页面准备好再执行”的开关。
我第一次接触 onload 就是因为图片操作的问题。当时想用 JavaScript 去改变图片的尺寸,但图片还没加载完,代码就执行了,尺寸获取不对。用了 window.onload 之后,问题就解决了。
什么是 onload 事件?
onload 事件在元素或页面加载完成时触发。它可以用在多种元素上,但最常见的是用在 window 对象或 <body> 标签上,表示整个页面加载完毕。
核心区别:
-
window.onload:等待整个页面加载,包括所有图片、样式、脚本、外部资源都加载完成才触发。 -
document.onload(或称DOMContentLoaded):当 HTML 结构解析完成时就会触发,不需要等待图片等资源。document.onload通常比window.onload更早触发。
onload 的三种使用方式
和其他事件类似,onload 也有几种绑定方式:
-
HTML 属性方式:
<body onload="函数名()"> -
DOM 属性方式:
window.onload = function -
addEventListener 方式:
window.addEventListener("load", function)
下面通过具体的代码示例来理解这些用法。示例都采用“代码号”学习环境的写法。
方式一:HTML 属性方式
这种方式最简单,直接在 <body> 标签里加 onload 属性。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>onload 示例</title>
<script>
function pageReady() {
alert("页面已加载,当前时间:2026年3月23日");
}
</script>
</head>
<body onload="pageReady()">
<h1>欢迎来到代码号学习平台</h1>
<p>页面加载完成后会弹出提示框</p>
</body>
</html>
说明:页面所有内容加载完成后,pageReady 函数被调用,弹出提示框。这种写法对于简单页面很方便,但 HTML 和 JavaScript 耦合在一起,项目复杂后不太利于维护。
方式二:DOM 属性方式
把事件绑定放在 JavaScript 里,用 window.onload 赋值。
<!DOCTYPE html>
<html>
<head>
<style>
#demoBox {
width: 200px;
height: 200px;
border: 2px solid #3498db;
margin-top: 20px;
transition: all 0.3s;
}
</style>
</head>
<body>
<h3>window.onload 示例(DOM 属性方式)</h3>
<p>页面加载完成后,下面这个方块会改变样式</p>
<div id="demoBox"></div>
<script>
// 使用 window.onload 确保 DOM 加载后再执行
window.onload = function() {
let box = document.getElementById("demoBox");
box.style.backgroundColor = "#e74c3c";
box.style.width = "300px";
box.style.height = "300px";
box.style.borderRadius = "10px";
console.log("页面加载完成,样式已更新");
};
</script>
</body>
</html>
说明:页面加载完成后,方块的颜色、尺寸、圆角都会改变。注意这里用了 window.onload,确保所有资源(包括样式)都就绪后才操作元素。
注意:这种赋值方式,如果后面再给 window.onload 赋值另一个函数,前面的会被覆盖。所以如果需要多个初始化操作,更推荐用 addEventListener。
方式三:addEventListener 方式
这是推荐的做法,可以给 load 事件绑定多个处理函数,互不影响。
<!DOCTYPE html>
<html>
<head>
<style>
.status {
padding: 10px;
margin: 10px 0;
background-color: #f8f9fa;
border-left: 4px solid #3498db;
}
</style>
</head>
<body>
<h3>addEventListener 方式绑定 load 事件</h3>
<div id="status1" class="status">等待页面加载...</div>
<div id="status2" class="status">等待页面加载...</div>
<script>
let statusDiv1 = document.getElementById("status1");
let statusDiv2 = document.getElementById("status2");
// 第一个初始化函数
function initFirst() {
statusDiv1.innerHTML = "第一个初始化任务完成,时间:" + new Date().toLocaleString();
statusDiv1.style.borderLeftColor = "#2ecc71";
}
// 第二个初始化函数
function initSecond() {
statusDiv2.innerHTML = "第二个初始化任务完成,开始加载用户数据";
statusDiv2.style.borderLeftColor = "#e67e22";
// 模拟加载数据
console.log("可以在这里发起 API 请求");
}
// 第三个函数:记录加载完成日志
function logLoadComplete() {
console.log("页面加载完成,所有资源就绪");
}
// 绑定多个处理函数
window.addEventListener("load", initFirst);
window.addEventListener("load", initSecond);
window.addEventListener("load", logLoadComplete);
</script>
</body>
</html>
说明:页面加载完成后,三个处理函数会按绑定顺序依次执行。这种方式适合需要执行多个初始化任务的场景,比如同时更新 UI、请求数据、记录日志等。
window.onload 与 DOMContentLoaded 的区别
这是开发中经常混淆的两个概念。理解它们的区别,对写出健壮的代码很重要。
| 事件 | 触发时机 | 适用场景 |
|---|---|---|
DOMContentLoaded |
HTML 结构解析完成,无需等待图片、样式等外部资源 | 操作 DOM 结构、绑定事件、不需要依赖图片尺寸的逻辑 |
window.onload / load |
页面所有资源(图片、样式、脚本)都加载完成 | 需要获取图片尺寸、操作 Canvas、依赖外部资源的场景 |
<!DOCTYPE html>
<html>
<head>
<style>
.info {
padding: 8px;
margin: 5px 0;
background-color: #ecf0f1;
}
</style>
</head>
<body>
<h3>DOMContentLoaded 与 window.onload 的区别</h3>
<div id="logArea"></div>
<img id="testImage" src="https://www.ebingou.cn/200/150?random=1" style="display:none;">
<script>
let logDiv = document.getElementById("logArea");
function addLog(msg) {
let p = document.createElement("p");
p.className = "info";
p.innerHTML = msg;
logDiv.appendChild(p);
}
// DOMContentLoaded: DOM 结构就绪,不等待图片
document.addEventListener("DOMContentLoaded", function() {
addLog("DOMContentLoaded 触发: HTML 结构已解析,但图片可能还在加载");
let img = document.getElementById("testImage");
addLog("图片尺寸(DOMContentLoaded时): " + img.clientWidth + " x " + img.clientHeight);
});
// window.onload: 等待所有资源
window.addEventListener("load", function() {
addLog("window.onload 触发: 所有资源(包括图片)已加载完成");
let img = document.getElementById("testImage");
addLog("图片尺寸(window.onload时): " + img.clientWidth + " x " + img.clientHeight);
});
</script>
</body>
</html>
说明:运行这个例子会看到,DOMContentLoaded 先触发,此时图片可能还没加载完,所以图片尺寸可能是 0;而 window.onload 后触发,此时图片已经加载完成,可以正确获取尺寸。
个人建议:如果只是操作 DOM 结构、绑定事件,用 DOMContentLoaded 就够了,它触发更快,用户体验更好。如果依赖图片尺寸或外部资源,才需要用 window.onload。
实战示例:页面加载后初始化组件
在项目中,onload 经常用于初始化各种组件,比如轮播图、图表、表单验证等。
<!DOCTYPE html>
<html>
<head>
<style>
.gallery {
display: flex;
gap: 10px;
margin-top: 20px;
}
.gallery img {
width: 150px;
height: 100px;
object-fit: cover;
cursor: pointer;
transition: transform 0.2s;
}
.gallery img:hover {
transform: scale(1.05);
}
#selectedInfo {
margin-top: 15px;
padding: 10px;
background-color: #f8f9fa;
border-radius: 5px;
}
</style>
</head>
<body>
<h3>页面加载后初始化图片画廊</h3>
<div class="gallery" id="gallery">
<img src="https://www.ebingou.cn/id/101/150/100" alt="风景1">
<img src="https://www.ebingou.cn/id/104/150/100" alt="风景2">
<img src="https://www.ebingou.cn/id/106/150/100" alt="风景3">
</div>
<div id="selectedInfo">点击任意图片查看信息</div>
<script>
// 初始化函数:等页面加载完成后执行
function initGallery() {
let images = document.querySelectorAll("#gallery img");
let infoDiv = document.getElementById("selectedInfo");
images.forEach((img, index) => {
img.addEventListener("click", function() {
infoDiv.innerHTML = `你点击了第 ${index + 1} 张图片,图片来源: ${img.src}`;
infoDiv.style.backgroundColor = "#d4edda";
infoDiv.style.borderLeft = "4px solid #28a745";
});
});
console.log("图片画廊初始化完成,时间:2026年3月23日");
}
// 使用 window.onload 确保图片加载完成后再绑定事件
window.onload = initGallery;
</script>
</body>
</html>
说明:页面加载完成后,为每张图片绑定点击事件。因为图片尺寸信息可能用不到,用 DOMContentLoaded 其实也行,但这里用 window.onload 确保图片就绪。
本节课程知识要点
-
onload的触发时机:window.onload等待所有资源(图片、样式、脚本)加载完成才触发;DOMContentLoaded只等待 HTML 结构解析完成。选择合适的时机可以优化页面响应速度。 -
绑定方式选择:HTML 属性方式适合简单页面;DOM 属性方式简单但会被覆盖;
addEventListener方式最灵活,支持多事件绑定,推荐用于正式项目。 -
window.onload与<body onload>的关系:两者本质是等价的,<body onload>最终也会调用window.onload。但用 JavaScript 绑定更符合关注点分离的原则。 -
常见应用场景:
-
初始化第三方组件(如图表库、地图)
-
获取图片尺寸后进行布局调整
-
页面加载完成后显示欢迎提示或登录状态检查
-
统计页面加载耗时(结合性能 API)
-
-
与
defer和async的关系:使用defer属性的外部脚本会在 DOM 解析完成后执行,类似DOMContentLoaded的时机;而window.onload会等待所有资源。理解这些差异有助于优化脚本加载策略。 -
注意事项:如果页面中有大量图片或第三方资源,
window.onload可能会延迟较长时间。这时候可以考虑把不依赖资源的初始化放到DOMContentLoaded里,只把必须等待图片的操作放在window.onload中。