Html 的生命周期

时间:2020-01-09
本文章向大家介绍Html 的生命周期,主要包括Html 的生命周期使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

零、序言

  vue 用多了,自然离不开生命周期。最近突发奇想,加上之前看过的文章中关于 script 标签中的 async 和 defer 的捣糨糊,决定整理一下,攻克这个模糊点。

  当然,最多的还是与 script 标签相关的前两个周期,后俩个周期并没有过多的复杂点,因此会着重描述前两个。

  参考文章:

    1.页面生命周期

    2.HTML,javascript,image等加载,DOM解析,js执行生命周期

一、页面周期

  1.DOMContentLoaded - 浏览器已经加载了 Html, DOM 树已经构建完毕,但是 img 和外部样式表等资源可能还没有下载完毕。

  2.load - 浏览器已经完全加载了所有资源。

  3.beforeunload - 用户即将离开页面。

  4.unload - 用户离开页面。

  每一个事件都有特定的用途,前两个如其名,beforeunload 会给用户弹出个确认框,unload 则不会。

二、DOMContentLoaded

  DOMContentLoaded 事件由 document 对象触发,我们可以使用 addEventListener 来触发。

  正如前文所说,在这个事件触发的时候,我们如果获取某些 img 的宽度和高度的话,得到的可能是0。

  当然这里是有陷阱的。

  1. 与脚本(<script />)

    首先有一点,浏览器的 UI 渲染线程和 JS 引擎是互斥的,当 JS 引擎执行时 UI 线程会被挂起。因此,当浏览器在解析 HTML 时遇到 <script /> 时,将不会继续构建 DOM 树,转而取解析、执行脚本,所以 DOMContentLoaded 有可能在所有脚本执行完毕之后触发。

    外部脚本(通过 src  引入)的加载和解析和自带的一样会暂停 DOM 树的构建,这里  DOMContentLoaded 会等待。

    不过有两个特殊的情况,如果外部脚本上带有 async 或者 defer 属性,那么浏览器会继续执行 DOM 解析而不需要等待脚本的完全执行,所以这一直时外部脚本的优化方案之一。(async 和 defer 属性仅对外部脚本起作用, 当 src 不存在的时候会被自动忽略)

    关于 async 和 defer 与 DOM 的解析顺序如下图所示:

    既然提到了 async 和 defer,  也顺带整理一下他们的异同:

  async defer
顺序 带有 async 的脚本是优先执行先加载完的脚本,即他们在页面中的顺序并不保证他们的执行顺序。 带有 defer 的脚本时按照他们在页面中出现的顺序依次执行。
DOMContentLoaded 带有async的脚本也许会在页面没有完全下载完之前就加载,这种情况会在脚本很小或本缓存,并且页面很大的情况下发生。 带有defer的脚本会在页面加载和解析完毕后执行,刚好在 DOMContentLoaded之前执行。

    所以 async 用在完全没有依赖和被依赖的脚本上。

三、load

  load 事件是在 window 对象上的,这与 DOMContentLoaded 不同。该事件在所有文件包括样式表,图片和其他资源下载完毕后触发。既然这样规定,自然该干啥干啥,没什么明显的陷阱。

四、beforeunload

  如果用户即将离开页面或关闭窗口时,beforeunload 事件将会被触发以进行额外的确认。举个例子:

window.onbeforeunload = function() {
  return "There are unsaved changes. Leave now?";
};

  当然,如果在 chrome 和 firefox 浏览器中会忽略返回的自定义的字符串,这是出于安全考虑的。

五、unload

  unload 事件与 load 事件一样,是在 window 对象上的,触发时间为用户关闭该页面的时候,我们可以做一些不存在延时的任务,比如关闭弹层等等。

六、readyState

  document.readyState 这个只读属性可以告诉程序当前文档加载到哪一个步骤,它有三个值:

    1. loading - 加载,document 仍在加载中;

    2. interactive - 互动,文档已经完成加载,文档已被解析,但是诸如图像,样式表和框架之类的子资源仍在加载。

    3. complete - 文档和所有子资源已完成加载。状态表示 load 事件即将被触发。

  而这个属性的每次改变同样有一个事件可以监听:

document.addEventListener('readystatechange', () => console.log(document.readyState));

   不过这个 change 事件很少会被用到,可能出现的地方在某些第三方类库中判断一些依赖关系等地方。不详述,具体可移步文首的文章或者 MDN。

原文地址:https://www.cnblogs.com/cc-freiheit/p/12125687.html