我们都知道,网页是浏览器加载、解析 HTML 而生。浏览器在解析完 HTML 后会构造出我们熟悉的 DOM 树,而通过 DOM 树,开发者就能容易地通过 JavaScript 去操作 DOM 节点,让网页不只是能看,而是能够互动。而网页与 DOM 也有我们熟知的生命周期,例如很常听到的 DOMContentLoaded ,以及面试中常会被问到的“ DOMContentLoaded 与 load 事件有什么不同?”
DOMContentLoaded 与 load 事件有什么不同
DOMContentLoaded 是当 DOM 构造完成后会触发的事件,因此只要当 HTML 文件完全加载、解析完后就会出发。这个时候 CSS 的样式表、图片等可能还没完全加载。因为很多 JavaScript 脚本,需要等到 DOM 节点被完整创建出来后,才能够使用,不然没有 DOM 节点,就没办法去做操作;所以 DOMContentLoaded 可以帮助开发者侦测什么时候可以执行这些 JavaScript 脚本。
load ( window.onload) 这个事件,则是在 HTML 文件完全加载、解析,以及 CSS 样式表、图片等各类资源都加载好后,才会被触发。所以可以理解成网页完整加载,才会触发 load 事件。也因此, load 会是在 DOMContentLoaded 之后被触发。如果 JavaScript 的逻辑会去改动到样式、图片等,就会更适合用 load 而非 DOMContentLoaded 帮助我们侦测。
我们也可以从另一个角度理解 DOMContentLoaded 与 load 事件的不同。在 document 对象有个 readyState 的属性 详见此 MDN文档,它有三个值一个是 loading 这代表 HTML 文件正在被解析中;第二个是 interactive 这代表 HTML 文件已经完成读取和解析,而 DOMContentLoaded 已经被触发,所以已经可以有互动了;最后则是 complete ,当进到这状态时,就会触发 load 事件。
beforeunload 与 unload 的触发时机与作用
DOMContentLoaded 与 load 事件是在侦测 DOM 与网页的创建完成,是在生命周期的开始;而 beforeunload 与 unload 则是在侦测声明周期的结尾,意即在网页要被关闭时触发。
beforeunload ( window.onbeforeunload) 是在使用者要离开网页前会被触发,例如要去别页、关闭分页等等的情况时,会触发这个事件。它的用途是可以让开发者在使用者要离开前,能够做点什么。常见的使用场景,是使用者要离开网页前,会跳出一个弹跳视窗,询问使用者是不是真的要离开或关闭网页,这就是通过 beforeunload 的事件触发,来得知应该要跳出这个视窗。
至于 unload ( window.onunload) 则是在离开或关闭网页后,才会被触发;所以它的触发时机是在 beforeunload 之后。如果我们要有弹跳视窗,不能用 unload 因为会太晚,我们会需要 beforeunload。而 unload 的用途通常会是用来埋数据分析,因为是在使用者离开网页时触发,我们就可以得知使用者确切是在什么时机离开了网页。