JavaScript:复制文档DOM而不引用

时间:2016-02-02 17:32:39

标签: javascript dom

是否可以在没有引用的情况下复制文档DOM(或其中的一部分)?

例如:

BodyCopy = document.body;
document.body.querySelector('#example').innerHTML = '<p>foo</p>';
BodyCopy.querySelector('#example').innerHTML = '<p>bar</p>';

// will output <p>bar</p>, but should be <p>foo</p>
console.log(document.body.querySelector('#example').innerHTML);

// will output <p>bar</p>
console.log(BodyCopy.querySelector('#example').innerHTML);

更新

好的,clondeNode()似乎首先工作,但如果我这样做

BodyCopy = document.body.cloneNode(true);
document.body.querySelector('#example').innerHTML = '<p>foo</p>';
BodyCopy.querySelector('#example').innerHTML = '<p>bar</p>';

// will output <p>foo</p>
console.log(document.body.querySelector('#example').innerHTML);

// will output <p>bar</p>
console.log(BodyCopy.querySelector('#example').innerHTML);

// Show edited copy
document.body = BodyCopy;

document.body.querySelector('#example').innerHTML = '<p>foo</p>';
BodyCopy.querySelector('#example').innerHTML = '<p>bar</p>';

// will output <p>bar</p>, but should be <p>foo</p>
console.log(document.body.querySelector('#example').innerHTML);

// will output <p>bar</p>
console.log(BodyCopy.querySelector('#example').innerHTML);

它不会像我期望的那样起作用。请参阅JSFiddle

3 个答案:

答案 0 :(得分:3)

您并未将DOM复制到任何位置,而是将document.body分配给名为BodyCopy的变量。

您需要在作业中使用cloneNode()

BodyCopy = document.body.cloneNode(true);
var BodyCopy = document.body.cloneNode(true);
document.body.querySelector('#example').innerHTML = '<p>foo</p>';
BodyCopy.querySelector('#example').innerHTML = '<p>bar</p>';

// Now outputs <p>foo</p>
console.log(document.body.querySelector('#example').innerHTML);

// Now outputs <p>bar</p>
console.log(BodyCopy.querySelector('#example').innerHTML);

jsFiddle Demo

答案 1 :(得分:1)

在执行修改之前,您需要clone the node

BodyCopy = document.body.cloneNode(true);

现在您有副本而不是参考。

修改

如果您想将旧的document.body替换为新的BodyCopy,则应修改其内容,而不是其内容:

document.body.innerHTML = BodyCopy.innerHtml;

答案 2 :(得分:1)

BodyCopy = document.body.cloneNode(true);
// ...
document.body = BodyCopy;

如果要替换节点,请使用replaceChild

let rootNode = document.documentElement;
let currentBody = document.body;
rootNode.replaceChild(BodyCopy, currentBody);

这应该如何根据html规范实现body setter function

如果你想让副本独立于新内容,你必须在更换旧内容之前再次克隆它;

应尽可能避免操作innerHTML,因为它必须通过HTML序列化程序和解析器对节点进行往返。