简体   繁体   中英

parentNode is null with MutationObserver.observe(document.body

I want to track some special tags as UI component, eg <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,

在此输入图像描述

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM