📅  最后修改于: 2023-12-03 15:27:25.114000             🧑  作者: Mango
在前端开发中,我们经常需要等待页面的DOM元素加载完毕后再执行JavaScript代码,本文将介绍几种方法来等待DOM加载完成后执行JavaScript。
window.onload
事件window.onload
事件会在页面的所有资源文件加载完成后触发,包括图片、样式表、JavaScript 文件等等,所以它会等待整个页面包括DOM元素都加载完成后才执行注册的事件处理函数。
window.onload = function() {
// DOM和资源文件都已经加载完成了
};
但是,window.onload
有一个致命的缺陷:它只能注册一个事件处理函数,后来的赋值会覆盖前面的,如果有多个代码段需要等待DOM加载完成后执行,就会出现问题。
DOMContentLoaded
事件DOMContentLoaded
事件会在页面的DOM元素加载完成后触发,不会等待其他资源文件加载完成,所以它比 window.onload
更快触发。
document.addEventListener("DOMContentLoaded", function() {
// DOM已经加载完成了
});
但是需要注意,DOMContentLoaded
事件在IE8及以下版本的浏览器不支持。
defer
属性在 HTML5 中,defer
属性可以用于标记需要延迟执行的JavaScript文件。当浏览器解析到该标记时,会在后台继续解析HTML文件,而不会阻塞DOM元素的构建和用户的交互操作。
<script src="your-script.js" defer></script>
需要注意的是,defer
属性只对外部JavaScript文件有效,而且只有在 IE9 及以上版本、Chrome、Firefox 和 Opera 浏览器中才被支持。
async
属性async
属性也可以用于标记需要异步执行的JavaScript文件。它和 defer
属性类似,但是它不保证脚本的执行顺序,可能出现偶然的脚本之间的竞争关系。
<script src="your-script.js" async></script>
需要注意的是, async
属性同样只对外部JavaScript文件有效,而且只有在 IE10 及以上版本、Chrome、Firefox、Opera 和 Safari 浏览器中才被支持。
requestAnimationFrame
requestAnimationFrame
可以在下一次浏览器执行重绘事件前,调用指定的函数,由于重绘事件是在 DOM 构建完成之后才开始的,所以可以用它来等待DOM元素的加载。
function waitForDomReady(callback) {
if (document.readyState === "complete" || document.readyState === "interactive") {
callback();
} else {
requestAnimationFrame(() => waitForDomReady(callback));
}
}
使用方法:
waitForDomReady(function() {
// DOM已经加载完成了
});
MutationObserver
MutationObserver
是一个新的API,它可以观察DOM树的变化,并得到相应的通知。可以使用它来等待DOM元素的加载。
function waitForDom(selector, callback) {
const observer = new MutationObserver(function(mutations, observer) {
if (document.querySelector(selector)) {
observer.disconnect();
callback();
}
});
observer.observe(document.documentElement, { childList: true, subtree: true });
}
使用方法:
waitForDom("#your-element", function() {
// #your-element 元素已经加载完成了
});
以上是几种等待DOM加载JavaScript的方法,各有优缺点,需要根据实际情况选择适合的方法。