使用 MutationObserver 时,DOM 中似乎不存在子节点
ChildNodes seemingly not existing in DOM while using MutationObserver
我正在尝试使用 MutationObserver 来观察 DOM 中的变化,但似乎我无法访问“大”子节点。我已经为观察者配置了子树和 childList 值。据我了解,不可能通过 MutationObserver 获得添加的子列表或更改的整个 DOM 树,它所做的只是观察更改。相反,您应该使用 getElementById。
我试过在观察到变化后使用getElementById在DOM中找到相关的“父”节点,然后爬取所有子节点。虽然我仍然没有在 childNodes 上点击。
我假设先将“父”节点插入到 DOM 上,然后再将子节点插入到“父”节点上,尽管这些事件不会在出于某种原因观察者。
我怀疑我可能需要在观察变化时更新 MutationObserver 的目标,然后继续使用 getElementById 并爬取这些节点。
关于为什么这些子节点不可观察的任何想法,and/or如何解决这个问题?
此致。
MutationObserver 的代码
function createObserver() {
const documentBody = document.body;
// callback function to execute when mutations are observed
const observer = new MutationObserver(mutationRecords => {
let addedNodes = []
for (const mut of mutationRecords) {
let arr = Array.prototype.slice.call(mut.addedNodes)
arr = arr.filter(node => popupTagNames.includes(node.tagName)); // Keep only selected tags
if (arr.length == 0) return; // don't keep empty
addedNodes = addedNodes.concat(arr)
let el = document.getElementById(addedNodes[0].id);
// Crawler
inspectNode(el)
}
})
const config = { attributes: true, childList: true, subtree: true, characterData: true }
observer.observe(documentBody, config)
}
让我们通过记录属于#qc-cmp2-container 元素的添加节点进行调查:
new MutationObserver(mutations => {
const parent = document.getElementById('qc-cmp2-container');
if (parent) console.log(...mutations.flatMap(m =>
[...m.addedNodes].filter(n => parent.contains(n)).map(n => n.cloneNode(true))));
}).observe(document, {subtree: true, childList: true});
我们将看到几个单独的调用:
- 主要的 #qc-cmp2-container 及其空子容器
- 内部 div 有很多子元素和文本
- 添加了两个额外的内部元素
最 resource-effective 解决方案是使用超快速 getElementById 检查等待父级,然后切换到观察父级:
function waitForId(id, callback) {
let el = document.getElementById(id);
if (el) {
callback(el);
} else {
new MutationObserver((mutations, observer) => {
el = document.getElementById(id);
if (el) {
observer.disconnect();
callback(el);
}
}).observe(document, { subtree: true, childList: true });
}
}
waitForId('qc-cmp2-container', parent => {
new MutationObserver((mutations, observer) => {
// do something
}).observe(parent, { subtree: true, childList: true });
});
我正在尝试使用 MutationObserver 来观察 DOM 中的变化,但似乎我无法访问“大”子节点。我已经为观察者配置了子树和 childList 值。据我了解,不可能通过 MutationObserver 获得添加的子列表或更改的整个 DOM 树,它所做的只是观察更改。相反,您应该使用 getElementById。
我试过在观察到变化后使用getElementById在DOM中找到相关的“父”节点,然后爬取所有子节点。虽然我仍然没有在 childNodes 上点击。
我假设先将“父”节点插入到 DOM 上,然后再将子节点插入到“父”节点上,尽管这些事件不会在出于某种原因观察者。
我怀疑我可能需要在观察变化时更新 MutationObserver 的目标,然后继续使用 getElementById 并爬取这些节点。
关于为什么这些子节点不可观察的任何想法,and/or如何解决这个问题?
此致。
MutationObserver 的代码
function createObserver() {
const documentBody = document.body;
// callback function to execute when mutations are observed
const observer = new MutationObserver(mutationRecords => {
let addedNodes = []
for (const mut of mutationRecords) {
let arr = Array.prototype.slice.call(mut.addedNodes)
arr = arr.filter(node => popupTagNames.includes(node.tagName)); // Keep only selected tags
if (arr.length == 0) return; // don't keep empty
addedNodes = addedNodes.concat(arr)
let el = document.getElementById(addedNodes[0].id);
// Crawler
inspectNode(el)
}
})
const config = { attributes: true, childList: true, subtree: true, characterData: true }
observer.observe(documentBody, config)
}
让我们通过记录属于#qc-cmp2-container 元素的添加节点进行调查:
new MutationObserver(mutations => {
const parent = document.getElementById('qc-cmp2-container');
if (parent) console.log(...mutations.flatMap(m =>
[...m.addedNodes].filter(n => parent.contains(n)).map(n => n.cloneNode(true))));
}).observe(document, {subtree: true, childList: true});
我们将看到几个单独的调用:
- 主要的 #qc-cmp2-container 及其空子容器
- 内部 div 有很多子元素和文本
- 添加了两个额外的内部元素
最 resource-effective 解决方案是使用超快速 getElementById 检查等待父级,然后切换到观察父级:
function waitForId(id, callback) {
let el = document.getElementById(id);
if (el) {
callback(el);
} else {
new MutationObserver((mutations, observer) => {
el = document.getElementById(id);
if (el) {
observer.disconnect();
callback(el);
}
}).observe(document, { subtree: true, childList: true });
}
}
waitForId('qc-cmp2-container', parent => {
new MutationObserver((mutations, observer) => {
// do something
}).observe(parent, { subtree: true, childList: true });
});