为什么在附加documentFragment时需要使用cloneNode?

cod*_*aig 8 javascript dom documentfragment backbone.js

我一直在寻找在Backbone.js应用程序中使用documentFragments,并想知道为什么我看到在将documentFragment附加到父DOM元素时使用"cloneNode"的示例.

这里可以看到一个例子.如果你低头看看DocumentFragment部分,你会看到:

oFrag = document.createDocumentFragment();
for (var i = 0, imax = aElms.length; i < imax; i++) {
 oFrag.appendChild(aElms[i]);
}

o.innerHTML = '';
o.appendChild(oFrag.cloneNode(true));
Run Code Online (Sandbox Code Playgroud)

为什么"oFrag"被克隆而不是仅仅附加它?另一篇博客文章没有使用"cloneNode"(作为比较).

ole*_*leq 7

您的第一个链接指的是autor使用的博客帖子,document.getElementsByTagName而不是document.getElementById测试用例.如果要为多个元素(即:div)赋予相同的元素documentFragment,则必须克隆它:

如果child是对文档中现有节点的引用,则appendChild将其从当前位置移动到新位置(即,在将节点附加到其他节点之前,不需要从其父节点中删除该节点).

这也意味着节点不能同时位于文档的两个点.因此,如果节点已经有父节点,则首先将其删除,然后附加到新位置.

通过MDN

很可能是作者(或其他人)在不考虑这一点的情况下复制粘贴代码.自己试试 - 你可以appendChild不使用cloneNode,一切正常.

另一种可能性是,在jsperf上创建此测试用例的人并没有太多准备代码如何工作,并担心第一个测试将清空aElms数组,它将不再工作.事实上,准备代码在每次定时迭代之前执行,因此不必担心其内容.

最后一件事可能是性能问题.如果您确实想测试实际插入,则需要克隆节点.否则,您将测试树重新附加(请参阅上面的MDN链接).

另请注意,克隆会破坏事件监听器.

快乐的片段'!;)