页面生命周期
参考:https://segmentfault.com/a/1190000011468675
DOMContentLoaded
html文档完全解析和加载完后执行,可能不会等待外部样式表与图片的加载。
DOM加载完毕,js可以访问DOM节点。
1. 由document对象触发
document.addEventListener('DOMContentLoaded', () => { console.log(1) })
2. 事件不会等待图片加载完成,如下
<img src="https://i04piccdn.sogoucdn.com/58de4ba104e6cc35" alt="" id="img"> <script> const img = document.getElementById('img') document.addEventListener('DOMContentLoaded', () => { console.log(`图片大小 ${img.offsetWidth} x ${img.offsetHeight}`) //图片并没有加载完成,所以尺寸为0 x 0 console.log(1) }) </script>
3. 同步javascript会暂停DOM构建(UI渲染引擎和JS引擎是互斥的,当JS执行时,UI渲染线程会暂时挂起)。所以DOMContentLoaded会在脚本完成后触发,例如
document.addEventListener('DOMContentLoaded', () => { console.log('DOMContentLoaded触发了') }) for (let i = 0; i <= 3; i++) { console.log(i) } //打印顺序 0 1 2 3 DOMContentLoaded触发了
4. 外部脚本的加载与解析同样会暂停DOM树的构建
<script> document.addEventListener('DOMContentLoaded', () => { console.log('DOMContentLoaded触发了') }) </script> <script src="./test.js"></script>
test.js中
for (let i = 0; i <= 3; i++) { console.log(i) }
打印结果仍然是0 1 2 3 DOMContentLoaded触发了
5. async和defer会使script标签异步加载,不会影响DOM树构建。
具体可参考链接:https://www.cnblogs.com/lianglanlan/p/14750948.html
6. link标签的位置决定了DOMContentLoaded是否会等待当前样式表的加载。
如果link标签后有内联脚本,脚本必须等待样式表加载完才能执行,而DOMContentLoaded又必须等待脚本执行后才会触发。
7. 浏览器的自动补全(补全之前填写过的用户名密码)就是在DOMContentLoaded执行时进行
load
页面所有资源加载完毕,包括图片与外部样式表。
可以在此事件获取图片的大小
1. 由window对象触发
2.会等待外部资源加载完成
<img src="https://i04piccdn.sogoucdn.com/58de4ba104e6cc35" alt="" id="img"> <script> const img = document.getElementById('img') window.addEventListener('load', () => { console.log(`图片大小 ${img.offsetWidth} x ${img.offsetHeight}`) //图片加载完成,可以正确打印出图片尺寸 console.log(1) }) </script>
beforeunload
浏览器窗口关闭或刷新时触发。当前页面会触发一个确认对话框,询问是否真的需要离开。
window.onbeforeunload = function () { return "There are unsaved changes. Leave now?"; };
之前的浏览器可以在确认对话框中显示返回的字符串,但目前大多数浏览器都不支持,只是显示浏览器定义的信息
unload
文档或者一个子资源被卸载时触发,是在beforeunload之后发生的。
unload事件与beforeunload事件都遵循文档树:父iframe会在子iframe之前卸载
<!DOCTYPE html> <html> <head> <title>Parent Frame</title> <script> window.addEventListener('beforeunload', function (event) { console.log('1'); }); window.addEventListener('unload', function (event) { console.log('3'); }); </script> </head> <body> <iframe src="./child-frame.html"></iframe> </body> </html>
下面是child-frame.html的内容
<!DOCTYPE html> <html> <head> <title>Child Frame</title> <script> window.addEventListener('beforeunload', function (event) { console.log('2'); }); window.addEventListener('unload', function (event) { console.log('4'); }); </script> </head> <body> 123 </body> </html>
当刷新页面时,会按照1 2 3 4的顺序打印
readyState
readyState提出来整理了一篇,可查阅:https://www.cnblogs.com/lianglanlan/p/14754429.html