首页 > 解决方案 > InnerHTML 每次都会创建新节点(新引用)

问题描述

我正在通过创建一个文档对象,DOMImplementation.createHTMLDocument()并且正在插入一些带有 innerHTML 属性的 html。之后,我将节点附加到现实中,如下所示:

function appenderController (nodes,target,uid){

    for(let i = 0 ; i < nodes.children.length ; i++) {
        if(nodes.children[i].children.length > 0){
            if(nodes.nodeType === "9"){
                appenderController(nodes.children[i],target);
                continue;
            }

            let realnode = appender(target, nodes.children[i]);
            appenderController(nodes.children[i],realnode);

        }
        if (uid && nodes.children[i].nodeName.toLowerCase() === uid) {
            nodes.children[i].remove();
            return;
        }
        appender(target, nodes.children[i]);
    }




}

在某些情况下,我会在我们的文档中添加更多的 html,因为 innerhtml 会再次创建整个文档,所以我还为每个节点添加了特殊属性,以跟踪我已经附加了哪些节点。当我appenderController使用递归调用nodes = fakedocument.body但在另一个函数中我正在为我们的 fakedocument 更新 innerhtml 并且在 appenderController 的下一次迭代中它将继续在旧的 fakedocument.body 上迭代时,问题就出现了,我怎样才能保留对我的假的引用即使我使用 innerhtml 并再次更新节点,也要记录

例子:

var html='
    <html>
    <head>
    </head>
    <body>
    <div id="somediv1"></div>
    </body>
    </html>'
;

var dom = document.implementation.createHTMLDocument();

dom.documentElement.innerHTML = html;

var body = dom.body;

var html2='
    <html>
    <head>
    </head>
    <body>
    <div id="somediv1"></div>
    <div id="somediv2"></div>
    </body>
    </html>'
;

dom.documentElement.innerHTML = html2;

现在,如果我们查看“body”var,我们将没有“somediv2”,这正是我的函数中发生的事情,在某些时候,我正在更新我的假文档的 innerhtml,但“appenderController”继续迭代旧节点

标签: javascript

解决方案


为每个元素分配一个唯一的 ID。然后在真实 DOM 和临时 DOM 上按 ID 访问元素。

不要存储对元素的引用,而是存储它们的 ID。

——</p>

您还可以import从一个节点DOM到另一个节点,而不是使用 innerHTML 替换整个树。这种方法不会干扰迭代父元素。

https://developer.mozilla.org/en-US/docs/Web/API/Document/importNode


推荐阅读