JavaScript:将节点复制到 DocumentFragment

Posted

技术标签:

【中文标题】JavaScript:将节点复制到 DocumentFragment【英文标题】:JavaScript: Copy Node to DocumentFragment 【发布时间】:2017-06-06 02:32:22 【问题描述】:

我认为 DocumentFragment 的全部意义在于能够在不接触 DOM 的情况下构建内容,直到它准备就绪。

鉴于 DocumentFragment 不支持innerhtml,它可能有点乏味。另一方面,一旦构造完成,通过片段本身很容易将内容添加到现有的 DOM 节点。

如果我创建 div 而不将其添加到 DOM,我可以按照我喜欢的方式填充它,包括 innerHTML。据我所知,它应该不会对性能产生额外影响。

是否有一种简单的方法(即一行左右)将现有 DOM 节点的内容复制到 DocumentFragment?该过程如下所示:

var div=document.createElement('div');
var fragment=document.createDocumentFragment();
div.innerHTML='…';
//  copy contents to fragment
//  etc

这样我可以两全其美。

回答

下面是@KevBot 的答案,并入示例中:

var divTest=document.querySelector('div#test');

var html='<p>One</p><p>Two</p>';
var fragment=document.createRange().createContextualFragment(html);

divTest.appendChild(fragment);

【问题讨论】:

我喜欢这个问题,其中一些解决方案实现了一些晦涩的 javascript 如果我创建一个 div 而不将它添加到 DOM 中,我可以按照我喜欢的方式填充它,包括 innerHTML。据我所知,它应该不会对性能产生额外影响。 div 和 docFrag 之间的区别在于,当您将 div 附加到 DOM 时,它会与您添加的所有内容一起保留在那里。使用 docFrag,您可以将其附加到 DOM,并且您添加到其中的所有内容都在 DOM 中,但 docFrag 不在。当你把桌布拉出来但把盘子留在桌子上时,有点像那种桌布技巧。 【参考方案1】:

您可以使用appendChild 将新元素添加到片段中。

var div=document.createElement('div');
var fragment=document.createDocumentFragment();
div.innerHTML='…';

fragment.appendChild(div);

如果您只想将元素的内容注入到片段中,那么您可以遍历 childNodes 并将它们插入到片段中。

div.childNodes.forEach(function(node) 
    fragment.appendChild(node);
);

【讨论】:

感谢您的回答,但我不想要 div 本身。只是内容。 您可以使用childNodes 属性并遍历每个节点并将其注入到片段中。 div.childNodes.forEach(function(node) fragment.appendChild(node); );【参考方案2】:

试试这些尺寸

text = frag.appendChild( document.createTextNode( "insert text here" ) )

text = frag.appendChild( document.createTextNode( div.innerHTML ) )

text = frag.appendChild( document.createTextNode( div.textContent ) )

text 变量将保存文本节点,而您还将文本节点全部附加在一行中

【讨论】:

【参考方案3】:

你可以创建一个&lt;template&gt;元素,它是一个文档片段;设置template元素的.innerHTML,并使用.content属性获取template元素的.innerHTML

var template = document.createElement("template");
var div = document.createElement("div");
div.innerHTML = "<p>abc</p>";
template.innerHTML = div.innerHTML;
document.body.appendChild(template.content);

【讨论】:

【参考方案4】:

是的,您可以使用document.createRange 方法轻松创建带有 HTML 字符串的片段。

document.createRange 返回一个Range 对象,该对象有一个名为createContextualFragment 的方法,允许您从HTML 中获取片段。

function fragmentFromString(strHTML) 
  return document.createRange().createContextualFragment(strHTML);


let div = document.createElement('div');
div.innerHTML = '<p>Testing</p>';

let fragment = fragmentFromString(div.innerHTML);
console.log(fragment);
<div>
  <p>Random Content</p>
</div>

适用于所有主流浏览器和 IE11。

【讨论】:

感谢您的回答。它在 IE11 中工作的事实使它有点好,但是谁在乎其余的呢?我已经修改了我的问题示例以反映您的示例。 不客气。是的,即使是微软也已经放弃了对 ie10 及以下版本的支持。

以上是关于JavaScript:将节点复制到 DocumentFragment的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript DOM实战:创建和克隆元素

使用javascript将大型html表导出到excel

JavaScript50_终篇_编程进阶与BOM编程概览(3k字+)

HTML5 完美解决javascript中iphone手机和android手机复制文本到剪切板问题

DOM操作技术----动态脚本

将文件/块从 HDFS 复制到从节点的本地文件系统