Skip to content

Document Ready

元信息

  • 目标:解释"脚本在 head 里却找不到按钮"这一经典时序 bug——浏览器自上而下解析,脚本先于元素执行;掌握 DOMContentLoaded/window.onload/$(document).ready 的时机差异与正确用法
  • 关键概念:DOMContentLoaded、window.onload、document.ready、加载时序、事件绑定失败
  • 关联阶段:cp3
  • 常见误区:以为 js 代码放哪都一样(执行顺序即源码顺序,元素未解析则选择器落空);该等 DOM 时误用 window.onload 白等图片等全部资源;window.onload 多次绑定相互覆盖还以为是浏览器 bug

问题

浏览器先载入js代码(包含事件声明和处理函数),然后载入DOM元素,请问新元素是否绑定了事件?

<!DOCTYPE html>
<html>
<head>
  <title>Parcel Sandbox</title>
  <meta charset="UTF-8" />
  <link rel="stylesheet" href="/styles.css" />
</head>
<body>
  <h1>Hello world</h1>
</body>
</html>

button的点击事件会被处理吗?

  1. 浏览器从上到下解析HTML
  2. 当执行 <script> 中的代码时,<body> 中的按钮还没有被解析
  3. jQuery 选择器 $("#myButton") 找不到对应的DOM元素
  4. 事件绑定失败,按钮点击没有反应

基础概念:浏览器加载网页的过程

解决方案:Document Ready

DOMContentLoaded 事件确保我们的JavaScript代码只在DOM完全加载后才执行:

<!DOCTYPE html>
<html>
<head>
  <title>Parcel Sandbox</title>
  <meta charset="UTF-8" />
  <link rel="stylesheet" href="/styles.css" />
</head>
<body>
  <h1>Hello world</h1>
</body>
</html>

不同历史阶段的实现技术

javascript
// window.onload - 等待所有资源,不推荐
window.onload = function() {
    console.log("页面完全加载完成,包括所有图片");
};

// jQuery document.ready 
$(document).ready(function() {
    console.log("DOM准备就绪,可以操作元素了");
    // 此时图片可能还在加载
});

// 原生JavaScript 实现 document.ready
document.addEventListener('DOMContentLoaded', function() {
    console.log("DOM准备就绪");
});

🔄 document.ready vs window.onload

很多初学者会混淆这两个概念,让我们来对比一下:

特性$(document).readywindow.onload
触发时机DOM结构加载完成所有资源(图片、CSS、JS等)加载完成
等待图片❌ 不等待✅ 等待
等待CSS✅ 等待CSS文件加载✅ 等待CSS文件加载
执行速度⚡ 更快🐌 较慢
可多次绑定✅ 可以❌ 只能最后一次有效

📊 时间线对比图

应用场景

场景1:表单验证

import "./styles.css";

document.getElementById("app").innerHTML = `
<h1>Hello world</h1>
`;

📝 总结

  1. 确保时序正确:保证DOM元素在JavaScript操作前已经存在
  2. 提高用户体验:避免JavaScript错误,确保功能正常
  3. 优化加载性能:比window.onload更早执行,不等待图片等资源

核心要点:

  • 总是在操作DOM元素前使用 document.ready相关技术
  • 理解它与 window.onload 的区别
  • 选择合适的时机执行你的JavaScript代码
  • 考虑使用现代原生JavaScript替代方案