在 Vue 项目中判断页面加载完成

907 阅读2分钟

文档加载事件

我们知道 HTML 页面的生命周期有三个事件:

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

Vue onMounted

在 Vue 中,onMounted 是一个生命周期钩子,在组件被挂载到 DOM 上之后立即调用。此时,模板已经被渲染成最终的 DOM,但不保证外部资源(如图片、iframe)都已经加载完毕。

onMounted(() => {
  doSomething()
})

在其中做的操作会在 DOM 挂载之后就开始进行,所以如果是要判断图片加载或者网页完全加载完成,这样操作是不行的。

结合 load 事件和 onMounted

可以通过在 window 上监听 load 事件来确保所有资源加载完成后再执行某些操作。结合 Vue 的 onMounted 钩子,可以在组件挂载后立即进行一些初始的 DOM 操作,而在 load 事件回调中进行需要所有资源加载完成后才能执行的操作。

onMounted(() => {
  window.addEventListener('load', doSomething)
})

针对 Vue 优化

但是 Vue 单页面应用的路由切换,并不会重新进行 load 事件。此时虽然 onMounted 钩子里进行了 load 事件监听,但是因为页面已经load 完成,所以并不会触发。

如果想要每次进入页面都要进行某些操作,则可以通过 document.readyState 进行状态判断。

onMounted(() => {
  if (document.readyState === 'complete') {
    doSomething()
  } else {
    window.addEventListener('load', doSomething)
  }
})

readyState

document.readyState 属性可以为我们提供当前加载状态的信息。

它有 3 个可能值:

  • loading —— 文档正在被加载。
  • interactive —— 文档被全部读取。
  • complete —— 文档被全部读取,并且所有资源(例如图片等)都已加载完成。

还有一个 readystatechange 事件,会在状态发生改变时触发。readystatechange 事件是跟踪文档加载状态的另一种机制,它很早就存在了。现在则很少被使用。

  • document.readyState 是文档的当前状态,可以在 readystatechange 事件中跟踪状态更改:

    • loading —— 文档正在被加载。
    • interactive —— 文档已被解析完成,与 DOMContentLoaded 几乎同时发生,但是在 DOMContentLoaded 之前发生。
    • complete —— 文档和资源均已加载完成,与 window.onload 几乎同时发生,但是在 window.onload 之前发生。

参考