【发布时间】:2021-03-25 08:28:50
【问题描述】:
目标和我的尝试
我正在尝试获取一种能够等到元素已经在 DOM 中的方法。我已经阅读了一些关于MutationObserver 的文章,并且我得到了这个方法,它应该可以完成我所需要的:
const waitForElement = async (queryString) => {
return new Promise((resolve) => {
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
const nodes = Array.from(mutation.addedNodes);
nodes.forEach((node) => {
console.log('NODE CUSTOM', node);
if (node.matches && node.matches(queryString)) {
observer.disconnect();
resolve(node);
}
});
});
});
observer.observe(document.documentElement, {
childList: true,
subtree: true,
});
});
};
那么,我可以简单地这样使用它:
await waitForElement('#id-of-element');
问题
问题是它实际上没有按预期工作:console.log 只记录“父母”元素,如果要搜索的元素在树的深处,似乎不是记录它(这是在更复杂的应用程序中使用的,因此它可能与异步调用等有关)。
问题
但是,我发现,我不需要遍历突变和节点数组,而只需要查看实际元素是否在 DOM 中,因此我实现了这个:
const waitForElement = async (queryString) => {
return new Promise((resolve) => {
let element;
const observer = new MutationObserver(() => {
element = document.querySelector(queryString);
if (element) {
observer.disconnect();
resolve(element);
}
});
observer.observe(document.documentElement, {
childList: true,
subtree: true,
});
});
};
这种方法将使用querySelector 方法检查每次突变后元素是否实际位于DOM 上。 它确实有效(另一个失败了),而且我发现它更容易阅读和理解,并且中间的循环更少。
这是一种值得推荐的方法吗?它会影响性能,还是和第一种方法一样?
谢谢!
【问题讨论】:
标签: javascript asynchronous document-ready mutation-observers queryselector