Javascript 我应该使用document.createDocumentFragment还是document.createElement

Javascript 我应该使用document.createDocumentFragment还是document.createElement,javascript,dom,Javascript,Dom,我是和DOM回流的,我想知道document.createDocumentFragment与document.createElement有何不同,因为在我将它们附加到DOM元素之前,它们似乎都不存在于DOM中 我做了一个测试(如下所示),所有测试所用的时间都完全相同(约95毫秒)。据猜测,这可能是因为没有样式应用于任何元素,所以可能没有回流 无论如何,根据下面的例子,为什么我要在插入DOM时使用createDocumentFragment而不是createElement,这两者有什么区别 var

我是和DOM回流的,我想知道
document.createDocumentFragment
document.createElement
有何不同,因为在我将它们附加到DOM元素之前,它们似乎都不存在于DOM中

我做了一个测试(如下所示),所有测试所用的时间都完全相同(约95毫秒)。据猜测,这可能是因为没有样式应用于任何元素,所以可能没有回流

无论如何,根据下面的例子,为什么我要在插入DOM时使用
createDocumentFragment
而不是
createElement
,这两者有什么区别

var htmz = "<ul>";
for (var i = 0; i < 2001; i++) {
    htmz += '<li><a href="#">link ' + i + '</a></li>';
}
htmz += '<ul>';

//createDocumentFragment
console.time('first');
var div = document.createElement("div");
div.innerHTML = htmz;
var fragment = document.createDocumentFragment();
while (div.firstChild) {
    fragment.appendChild(div.firstChild);
}
$('#first').append(fragment);
console.timeEnd('first');

//createElement
console.time('second');
var span = document.createElement("span");
span.innerHTML = htmz;
$('#second').append(span);
console.timeEnd('second');


//jQuery
console.time('third');
$('#third').append(htmz);
console.timeEnd('third');
var htmz=“
    ”; 对于(变量i=0;i<2001;i++){ htmz+='
  • '; } htmz+='
      '; //createDocumentFragment 控制台。时间(“第一”); var div=document.createElement(“div”); div.innerHTML=htmz; var fragment=document.createDocumentFragment(); while(第一个孩子){ 片段.appendChild(div.firstChild); } $('#first')。追加(片段); console.timeEnd('first'); //createElement 控制台。时间(“秒”); var span=document.createElement(“span”); span.innerHTML=htmz; $('#second')。追加(span); 控制台。时间结束('second'); //jQuery 控制台。时间(‘第三’); $('#third').append(htmz); 控制台。时间结束(“第三”);
不同之处在于,将文档片段添加到DOM时,它实际上会消失。所发生的情况是,文档片段的所有子节点都插入到DOM中插入文档片段的位置,而文档片段本身并没有插入。片段本身继续存在,但现在没有子对象

这允许您同时将多个节点插入DOM:

var frag = document.createDocumentFragment();
var textNode = frag.appendChild(document.createTextNode("Some text"));
var br = frag.appendChild(document.createElement("br"));
var body = document.body;
body.appendChild(frag);
alert(body.lastChild.tagName); // "BR"
alert(body.lastChild.previousSibling.data); // "Some text"
alert(frag.hasChildNodes()); // false

创建元素和文档片段之间的另一个非常重要的区别:

当您创建一个元素并将其附加到DOM中时,该元素以及子元素都会附加到DOM中

对于文档片段,仅附加子项

以下列情况为例:

var ul=document.getElementById(“ul_测试”);
//首先。添加文档片段:
(功能(){
var frag=document.createDocumentFragment();
var li=document.createElement(“li”);
li.appendChild(document.createTextNode(“文档片段”);
frag.appendChild(李);
ul.儿童(frag);
控制台日志(2);
}());
(功能(){
var div=document.createElement(“div”);
var li=document.createElement(“li”);
li.appendChild(document.createTextNode(“insidediv”);
儿童部(李);
ul.儿童(分部);
}());
示例列表:

感谢您的回复。您说它允许同时进行多个插入,但我可以使用doc.createElement实现这一点。唯一的区别是我必须先将元素包装在标记中,然后将其插入DOM。这就是我应该使用createDocumentFragment的原因吗?为了避免不必要的元素被插入DOM?是的,这绝对是使用它的一个原因。此外,文档片段可以包含任何类型的节点,而元素可以不包含;浏览器将其子节点移动到DOM。因此片段仍然存在,但插入后它将是空的。@inf3rno:因此我使用了“有效”一词,下面的解释与您的解释基本相同。我承认,我应该在回答中明确指出,片段仍然存在,没有子节点。@TimDown谢谢你的回答!如果我理解正确,关于性能,在内存中使用
createFragment
createElement
的效果大致相同,因为它们都批量更新DOM,而不是多次迭代更新。虽然
createFragment
的主要优点是它为您提供了选择免费附加的子元素的灵活性?如果我错了,请纠正我。