如何知道 window 的 load 事件已经触发
背景
为了使页面加载更快,常常将一些不重要的第三方脚本在页面完成加载后进行懒加载。
// 做一些不影响业务的事情
window.addEventListener('load', () => {
// 懒加载埋点分析
loadScript({
url: 'https://www.domain.com/test.js',
timeout: 10000
}).then(() => {
console.log('ok');
}).catch(console.error);
// 其他
// ...
});
因为 load
事件只会触发一次,如果在懒加载(load
)的脚本中又有懒加载的脚本,就会导致内嵌的脚本无法触发。
// 做一些不影响业务的事情
window.addEventListener('load', () => {
window.addEventListener('load', () => {
// 不能执行了
console.log('我无了');
});
});
解决方案
在 HTML 中 document.readyState
属性可以反应当前页面的加载状态。
uninitialized
- Has not started loading yetloading
- Is loadingloaded
- Has been loadedinteractive
- Has loaded enough and the user can interact with itcomplete
- Fully loaded
如果属性为 complete
则可认为当前页面已经加载完成。
/**
* 加载完成
* @param timeout {Number} 超时时间 / 单位:秒
* @return {Promise<Boolean>} document is loaded?
*/
function windowLoaded(timeout = 90) {
let loaded, loadFail;
const status = new Promise((resolve, reject) => {
loaded = resolve;
loadFail = reject;
});
if (document.readyState === 'complete') {
loaded('complete');
} else {
window.addEventListener('load', () => loaded('load'));
}
// 超过 timeout 秒后加载失败
setTimeout(() => loadFail('timeout'), timeout * 1000);
return status;
}
// load
windowLoaded()
.then(res => {
console.log(res);
})
.catch(console.error);
参考
HTML DOM readyState Property
What is the non-jQuery equivalent of '$(document).ready()'?
PerformanceTiming.loadEventEnd
Window: load event
版权声明
本博客所有的原创文章,作者皆保留版权。转载必须包含本声明,保持本文完整,并以超链接形式注明作者后除和本文原始地址:https://blog.mazey.net/1994.html
GitHub: https://github.com/mazeyqian
Blog: https://blog.mazey.net/
Blog: https://blog.mazey.net/