我的github

在JavaScript中,$(document).ready(function() {}) 的执行时机与主线程代码的关系如下:

核心结论:

不是等待所有JS主线程代码执行完才执行,而是 在DOM树构建完成(HTML解析完毕)后立即执行,与主线程代码的执行顺序取决于它们在文档中的位置。


详细机制:

  1. 触发条件
    $(document).ready() 在 DOM树构建完成(DOMContentLoaded事件触发) 时执行,无需等待图片、样式表等外部资源加载(与window.onload不同)。

  2. 与主线程代码的关系:

    • ready()定义在 <head> 中:
      主线程的同步代码(如<script>标签内的代码)会 优先执行(因为HTML解析遇到<script>时会暂停解析并执行脚本)。此时:

      <head>
        <script>
          console.log("主线程代码"); // 先执行
          $(document).ready(() => console.log("ready()回调")); // 后执行
        </script>
      </head>
    • ready()定义在 <body> 末尾:
      DOM树已基本构建完成,ready()回调可能 几乎立即执行:

      <body>
        <!-- 页面内容 -->
        <script>
          $(document).ready(() => console.log("ready()回调")); // 可能先于下方的同步代码执行
          console.log("主线程代码"); 
        </script>
      </body>
  3. 事件队列机制:
    ready()回调属于 异步任务,即使DOM已就绪,其回调仍需等待主线程的 当前执行栈清空 后才会执行:

    console.log("同步任务1");
    $(document).ready(() => console.log("ready回调"));
    console.log("同步任务2");
    
    // 输出顺序:
    // 同步任务1
    // 同步任务2
    // ready回调 (即使DOM早已就绪,仍需等待主线程空闲)

执行流程图解:

HTML解析开始
│
├─ 遇到<script>标签 → 暂停解析,执行同步JS代码
│   (主线程代码在此处运行)
│
├─ DOM树构建完成 → 触发`DOMContentLoaded`事件
│   → 将`ready()`回调推入异步队列
│
├─ 主线程执行栈清空 → 从异步队列中取出`ready()`回调执行
│
└─ 继续加载图片等资源 → 触发`window.onload`

关键总结:

  1. 不依赖主线程代码完成,依赖 DOM树构建完成。

  2. 执行顺序 由代码位置和异步队列机制共同决定:

    • 同位置的同步代码 优先于 ready()回调执行。

    • 即使DOM已就绪,回调也需 等待主线程空闲。

  3. window.onload的区别:
    ready() 在DOM就绪后执行(更快),window.onload 需等待所有资源加载完成(较慢)。

最佳实践:将初始化逻辑放在ready()中,确保操作DOM前结构已就绪,同时避免阻塞页面渲染。

参考:https://chat.deepseek.com/a/chat/s/f170584c-b103-46ac-9ebe-e754688832e2
posted on 2025-07-04 09:45  XiaoNiuFeiTian  阅读(64)  评论(0)    收藏  举报