admin管理员组文章数量:1414886
Fiddle: /
I would like to have one MutationObserver
that can detect all new nodes within itself. In the example, I have set {childList: true, subtree: true}
, but div#nested
does not appear in the MutationObserver
(shown in the console).
How can I have an observer detects any depth of child nodes?
const domObserver = new MutationObserver((records) => {
records.forEach((record) => {
console.log(record)
})
})
domObserver.observe(document.querySelector('#frame'), {childList: true, subtree: true})
// copy child nodes out of #template (as a string) and inject them into #frame for the observer to detect
document.querySelector('#frame').innerHTML = document.querySelector('#template').innerHTML
<div id="frame"></div>
<div id="template" style="display: none;">
<div class="level-1">
<div class="level-2">
<div id="nested">
I exist in the DOM but am not being seen by the MutationObserver
</div>
</div>
</div>
<div class="level-1">
<div class="level-2">
</div>
</div>
<div class="level-1">
<div class="level-2">
</div>
</div>
</div>
Fiddle: https://jsfiddle/7gj26hqu/
I would like to have one MutationObserver
that can detect all new nodes within itself. In the example, I have set {childList: true, subtree: true}
, but div#nested
does not appear in the MutationObserver
(shown in the console).
How can I have an observer detects any depth of child nodes?
const domObserver = new MutationObserver((records) => {
records.forEach((record) => {
console.log(record)
})
})
domObserver.observe(document.querySelector('#frame'), {childList: true, subtree: true})
// copy child nodes out of #template (as a string) and inject them into #frame for the observer to detect
document.querySelector('#frame').innerHTML = document.querySelector('#template').innerHTML
<div id="frame"></div>
<div id="template" style="display: none;">
<div class="level-1">
<div class="level-2">
<div id="nested">
I exist in the DOM but am not being seen by the MutationObserver
</div>
</div>
</div>
<div class="level-1">
<div class="level-2">
</div>
</div>
<div class="level-1">
<div class="level-2">
</div>
</div>
</div>
Share
Improve this question
edited Apr 20, 2020 at 4:08
ggorlen
58k8 gold badges114 silver badges157 bronze badges
asked Apr 20, 2020 at 4:01
somebodysomewheresomebodysomewhere
1,1561 gold badge13 silver badges26 bronze badges
1
-
It's working. It just takes a long time to load it all into the console. Do
const domObserver = new MutationObserver(records=>{ records.forEach(record=>{ console.log(record.target.innerHTML); }); });
– StackSlave Commented Apr 20, 2020 at 4:27
1 Answer
Reset to default 6It looks like when a container that's being observed has its innerHTML
set, the children of the container are emptied, and then new children get added fully intact. Using a synchronous observer (just so you can see what's happening), see how child nodes exist when the element is being appended:
// Look at results in browser console:
window.addEventListener('DOMNodeInserted', (e) => {
console.log(e.path[0].childNodes.length);
});
document.querySelector('#frame').innerHTML = document.querySelector('#template').innerHTML
<div id="frame"></div>
<div id="template" style="display: none;">
<div class="level-1">
<div class="level-2">
<div id="nested">
I exist in the DOM but am not being seen by the MutationObserver
</div>
</div>
</div>
<div class="level-1">
<div class="level-2">
</div>
</div>
<div class="level-1">
<div class="level-2">
</div>
</div>
</div>
The grandchild of the container being observed is attached to the child before the child gets attached to the container, so the subtree: true
doesn't see the attachment action.
To detect all child nodes inserted this way, you'll have to recursively iterate through all elements in the MutationRecord manually, despite the subtree: true
.
const recurse = (parent) => {
console.log(parent);
if (parent.childNodes) {
[...parent.childNodes].forEach(recurse);
}
};
const domObserver = new MutationObserver((records) => {
for (const record of records) {
for (const node of record.addedNodes) {
recurse(node);
}
}
})
domObserver.observe(document.querySelector('#frame'), {childList: true, subtree: true})
// copy child nodes out of #template (as a string) and inject them into #frame for the observer to detect
document.querySelector('#frame').innerHTML = document.querySelector('#template').innerHTML
<div id="frame"></div>
<div id="template" style="display: none;">
<div class="level-1">
<div class="level-2">
<div id="nested">
I exist in the DOM but am not being seen by the MutationObserver
</div>
</div>
</div>
<div class="level-1">
<div class="level-2">
</div>
</div>
<div class="level-1">
<div class="level-2">
</div>
</div>
</div>
Result:
If you want to use a TreeWalker instead:
const frame = document.querySelector('#frame');
const domObserver = new MutationObserver(() => {
// If the container's innerHTML was assigned to, iterate over all descendants:
const treeWalker = document.createTreeWalker(frame);
const nodes = [];
let currentNode = treeWalker.currentNode;
while (currentNode) {
nodes.push(currentNode);
currentNode = treeWalker.nextNode();
}
console.log(nodes);
});
domObserver.observe(frame, {
childList: true,
subtree: true
})
// copy child nodes out of #template (as a string) and inject them into #frame for the observer to detect
document.querySelector('#frame').innerHTML = document.querySelector('#template').innerHTML
<div id="frame"></div>
<div id="template" style="display: none;">
<div class="level-1">
<div class="level-2">
<div id="nested">
I exist in the DOM but am not being seen by the MutationObserver
</div>
</div>
</div>
<div class="level-1">
<div class="level-2">
</div>
</div>
<div class="level-1">
<div class="level-2">
</div>
</div>
</div>
本文标签: javascriptMutationObserver not picking up on child nodesStack Overflow
版权声明:本文标题:javascript - MutationObserver not picking up on child nodes - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745171097a2645978.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论