页面加载完成分阶段:DOMContentLoaded 表示 HTML 解析完毕、DOM 树就绪,可安全操作元素;load 事件则需等待所有资源(CSS、图片、iframe)全部加载完成。

页面加载完成不是单一事件,而是分阶段的——你要先明确自己真正需要等什么:是 DOM 结构就绪?还是所有图片、CSS、iframe 全部加载完?选错时机会导致脚本报错或布局错乱。
DOMContentLoaded 适合大多数 DOM 操作
这是最常用也最安全的时机,表示 HTML 解析完毕、DOM 树已构建完成,document.body 和所有元素可访问,但不等待 CSS、图片、iframe 等外部资源。
常见错误现象:
-
document.getElementById返回null—— 脚本执行太早,DOM 还没解析到对应标签 - 用
getComputedStyle获取样式值不准 —— CSSOM 可能未就绪,浏览器还没应用样式规则
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 把初始化菜单、绑定按钮点击、读取元素尺寸等操作放在这里
- 监听写法统一用
document.addEventListener('DOMContentLoaded', handler),IE9+ 原生支持,无需 polyfill - 即使监听代码写在
<head>里也安全,浏览器会缓存事件并自动派发 - 不要用
document.ready(非标准)或$(function(){})(依赖 jQuery)替代,除非项目已强耦合 jQuery
window.onload 等待全部资源加载完成
window.onload 触发时,页面及其所有子资源(图片、样式表、脚本、iframe)都已下载并解析完毕。它比 DOMContentLoaded 晚得多,尤其在网络慢或图片多时延迟明显。
使用场景:
- 需要精确测量图片渲染后的真实尺寸(比如瀑布流布局)
- 要确保第三方 iframe 已加载并可通信(如嵌入的视频播放器)
- 做全页面性能打点(如记录“首屏完全可见”时间)
注意点:
-
window.onload是window对象上的事件,不是document的 - 重复赋值
window.onload = fn1; window.onload = fn2;会覆盖,推荐用addEventListener('load', fn)避免冲突 - 如果页面含跨域 iframe,其加载状态无法被父页感知,
load不代表它一定 ready
新打开窗口如何判断加载完成
用 window.open() 打开空窗口(如 window.open('', '_blank'))后,直接监听 win.document.addEventListener('DOMContentLoaded') 或设置 win.onload 大概率失效。原因在于初始文档是 about:blank,没有标准加载流程,且受同源策略限制。
可靠方案是轮询 win.document.readyState:
- 当
win.document.readyState === 'complete'时,表示该窗口文档及其所有子资源已加载完毕 - 必须加防错:检查
win.closed和win.document是否存在,避免跨域报错或窗口已关闭 - 轮询间隔建议 ≥ 50ms,太频繁影响主线程;超时建议设为 10s,防止死循环
示例关键逻辑:
const checkReady = () => {
if (win.closed) return;
if (win.document && win.document.readyState === 'complete') {
console.log('新窗口已完全就绪');
return;
}
setTimeout(checkReady, 100);
};
checkReady();
readyState 变化可作为补充监控手段
document.readyState 有三个有效值:loading、interactive、complete。它不像事件那样“触发一次”,而是持续反映当前状态,适合做细粒度控制。
实操中容易忽略的点:
-
interactive阶段 DOM 已就绪,但 CSS 可能未加载完,此时调用offsetHeight可能返回 0 -
readystatechange事件会多次触发(loading → interactive → complete),需手动判断值再执行逻辑 - 不要依赖
uninitialized—— 现代浏览器已弃用该值,实际不会出现
如果你需要在 DOM 就绪但资源未全时提前做些轻量初始化(比如预占位、打日志),interactive 是比 DOMContentLoaded 更早的信号,但稳定性不如后者。
真正难的不是选哪个 API,而是理解你操作的 DOM 节点是否已被样式影响、是否依赖某张图片的尺寸、是否要和 iframe 通信——这些细节决定了该等 DOMContentLoaded 还是必须等到 complete,而不是背熟事件名就完事。



















