谈一谈对页面声明周期的理解

HTML页面的生命周期包含以下4个事件:

  1. DOMContentLoaded事件:浏览器已经完全加载HTML,并构建了DOM树,但像<img>和样式表之类的外部资源可能尚未加载完成。【DOM已经就绪,因此处理程序可以查找DOM节点,并初始化接口】
  2. load事件:浏览器不仅加载完成了HTML,还加载完成了所有外部资源:图片、样式等。【外部资源加载完成,样式已被应用,图片大小已知】
  3. beforeunload事件:用户正在离开页面:我们可以检查用户是否保存了更改,并询问他是否真的要离开。
  4. unload事件:用户几乎已经离开了,但是我们仍然可以启动一些操作,例如发送统计数据。

DOMContentLoaded和脚本

当浏览器处理一个HTML文档,并在文档中遇到<script>标签时,就会在继续构建DOM之前运行它。这是一种防范措施,因为脚本可能想要修改DOM,甚至对其执行document.write操作,所以DOMContentLoaded必须等待脚本执行结束后才能执行。

此规则有两个例外:

  • 具有async特性的脚本不会阻塞DOMContentLoaded
  • 使用document.createElement('script')动态生产并添加到网页的脚本也不会阻塞DOMContentLoaded

DOMContentLoaded和样式

外部样式表不会影响DOM,因此DOMContentLoaded不会等待它们。
但是这里有一个值得⚠️注意的点:如果在样式后面有一个脚本,那么该脚本必须等待样式表加载完成。原因是:脚本可能想要获取元素的坐标和其他与样式相关的属性,因此它必须等待样式加载完成。
(此时当DOMContentLoaded等待脚本时,它现在也在等待脚本前面的样式)

浏览器内建的自动填充

当我们在使用浏览器访问网页时,会使用到浏览器自动填充表单的功能。自动填充表单是在DOMContentLoaded中执行的。因此,如果DOMContentLoaded被需要加载很长时间的脚本延迟触发,那么自动填充也会等待。

window.onload

当整个页面,包括样式、图片和其他资源被加载完成时,会触犯window对象上的load事件。通过load属性获取此事件。

window.onunload

当访问者离开页面时,window对象上的unload事件就会被触发。我们可以在此事件上做一些不涉及延迟的操作,例如关闭相关的弹出窗口。

有一个值得注意的特殊情况是发送分析数据:
假设我们收集有关页面使用情况的数据:鼠标点击,滚动,被查看的页面区域等。自然地,当用户要离开的时候,我们希望通过 unload 事件将数据保存到我们的服务器上(该操作涉及到延迟问题)
有一个特殊的 navigator.sendBeacon(url, data) 方法可以满足这种需求。它在后台发送数据,转换到另外一个页面不会有延迟:浏览器离开页面,但仍然在执行 sendBeacon。当 sendBeacon 请求完成时,浏览器可能已经离开了文档,所以就无法获取服务器响应(对于分析数据来说通常为空)。还有一个 keep-alive 标志,该标志用于在 fetch 方法中为通用的网络请求执行此类“离开页面后”的请求。
如果我们要取消跳转到另一页面的操作,在这里做不到。但是我们可以使用另一个事件 —— onbeforeunload

window.onbeforeunload

如果访问者触发了离开页面的导航(navigation)或试图关闭窗口,beforeunload 处理程序将要求进行更多确认。如果我们要取消事件,浏览器会询问用户是否确定。

总结:

页面的生命周期事件:

  • 当 DOM 准备就绪时,document 上的 DOMContentLoaded 事件就会被触发。在这个阶段,我们可以将 JavaScript 应用于元素。诸如 <script>...</script><script src="..."></script> 之类的脚本会阻塞 DOMContentLoaded,浏览器将等待它们执行结束。图片和其他资源仍然可以继续被加载。

  • 当页面和所有资源都加载完成时,window 上的 load 事件就会被触发。我们很少使用它,因为通常无需等待那么长时间。

  • 当用户想要离开页面时,window 上的 beforeunload 事件就会被触发。如果我们取消这个事件,浏览器就会询问我们是否真的要离开(例如,我们有未保存的更改)。

  • 当用户最终离开时,window 上的 unload 事件就会被触发。在处理程序中,我们只能执行不涉及延迟或询问用户的简单操作。正是由于这个限制,它很少被使用。我们可以使用 navigator.sendBeacon 来发送网络请求。

文章作者: qinwei
文章链接: https://qw-null.github.io/2022/09/06/谈一谈对页面声明周期事件的理解/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 QW's Blog