Reputation: 5340
I want to track some special tags as UI component, e.g. <color>, <date>, so when such element is created and inserted to DOM, I can convert it to real functional html block.
Here's code, observe addedNodes on document.body.
function handleAddedNodes(nodes) {
[].forEach.call(nodes, function(node) {
if (!node.tagName)
return;
//how is it possible, node.parentNode is null?????
if (!node.parentNode) {
return;
}
});
}
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
handleAddedNodes(mutation.addedNodes);
});
});
observer.observe(document.body, {
childList : true,
subtree : true
});
It works fine as expected, but I also found a weird problem: no parentNode for some addedNodes(as "observe(document.body" means addedNodes should be descendants of document.body, right?)
The whole function works as an addon to a big frontend project, I don't know how the project mutate the DOM, set innerHTML or appendChild(too much code here). It also can not be debugged, as observe function is async, like event, no function call stack.
So I just want to know what could cause this, and even better if it can be reproduced with jsFiddle.
Well, seemed jsFiddle can reproduce this,
Upvotes: 8
Views: 2096
Reputation: 11353
If an element is added and then immediately (faster than the next setImmediate
is triggered) removed to a watched element of a MutationObserver
, the observer will notice and add a mutation
for both the addedNode
and the removedNode
- but as you've noticed the referenced element will not have a parent node.
Updated with example See fiddle
With your MutationObserver
from op the following code will call handleAddedNodes
thrice, once for an element thats been removed and once for an element that was appended to the removed element. The removed element will have no parent while the second element will have a parent.
var body = document.body;
var test = document.createElement("div");
var test2 = document.createElement("span");
body.appendChild(test);//adds childList mutation (addedNodes)
test.appendChild(test2);//adds subtree mutation (addedNodes)
body.removeChild(test);//adds mutation (removedNodes)
Upvotes: 6