[TOC]

页面生命周期:DOMContentLoaded,load,beforeunload,unload

HTML 页面的生命周期包含三个重要事件

  • DOMContentLoaded —— 浏览器已完全加载 HTML,并构建了 DOM 树,但像 11.26 加载文档和其他资源 - 图1 和样式表之类的外部资源可能尚未加载完成。
  • load —— 浏览器不仅加载完成了 HTML,还加载完成了所有外部资源:图片,样式等。
  • beforeunload/unload —— 当用户正在离开页面时。

    每个事件都是有用的

  • DOMContentLoaded 事件 —— DOM 已经就绪,因此处理程序可以查找 DOM 节点,并初始化接口。

  • load 事件 —— 外部资源已加载完成,样式已被应用,图片大小也已知了。
  • beforeunload 事件 —— 用户正在离开:我们可以检查用户是否保存了更改,并询问他是否真的要离开。
  • unload 事件 —— 用户几乎已经离开了,但是我们仍然可以启动一些操作,例如发送统计数据。

    页面生命周期事件

  • 当 DOM 准备就绪时,document 上的 DOMContentLoaded 事件就会被触发。在这个阶段,我们可以将 JavaScript 应用于元素。

    • 诸如 或 之类的脚本会阻塞DOMContentLoaded,浏览器将等待它们执行结束。
    • 图片和其他资源仍然可以继续被加载。
  • 当页面和所有资源都加载完成时,window 上的 load 事件就会被触发。我们很少使用它,因为通常无需等待那么长时间。
  • 当用户想要离开页面时,window 上的 beforeunload 事件就会被触发。如果我们取消这个事件,浏览器就会询问我们是否真的要离开(例如,我们有未保存的更改)。
  • 当用户最终离开时,window 上的 unload 事件就会被触发。在处理程序中,我们只能执行不涉及延迟或询问用户的简单操作。正是由于这个限制,它很少被使用。我们可以使用 navigator.sendBeacon 来发送网络请求。
  • document.readyState 是文档的当前状态,可以在 readystatechange 事件中跟踪状态更改:
    • loading —— 文档正在被加载。
    • interactive —— 文档已被解析完成,与 DOMContentLoaded 几乎同时发生,但是在 DOMContentLoaded 之前发生。
    • complete —— 文档和资源均已加载完成,与 window.onload 几乎同时发生,但是在 window.onload之前发生。

      脚本:async,defer

      当浏览器加载 HTML 时遇到 标签,浏览器就不能继续构建 DOM。它必须立刻执行此脚本。对于外部脚本 也是一样的:浏览器必须等脚本下载完,并执行结束,之后才能继续处理剩余的页面。
      这会导致两个重要的问题:
  1. 脚本不能访问到位于它们下面的 DOM 元素,因此,脚本无法给它们添加处理程序等。
  2. 如果页面顶部有一个笨重的脚本,它会“阻塞页面”。在该脚本下载并执行结束前,用户都不能看到页面内容。

这里有一些解决办法。例如,我们可以把脚本放在页面底部。此时,它可以访问到它上面的元素,并且不会阻塞页面显示内容。但是这种解决方案远非完美。例如,浏览器只有在下载了完整的 HTML 文档之后才会注意到该脚本(并且可以开始下载它)。对于长的 HTML 文档来说,这样可能会造成明显的延迟。

这里有两个