2010-08-03 69 views
72

我是reading about document fragments和DOM回流,并且想知道document.createDocumentFragmentdocument.createElement有什么不同,因为它看起来好像都不存在于DOM中,直到我将它们追加到DOM元素。我是否应该使用document.createDocumentFragment或document.createElement

我做了一个测试(下面),他们都花费了完全相同的时间(约95ms)。据猜测,这可能是由于没有适用于任何元素的样式,所以没有回流。

无论如何,基于下面的例子,为什么插入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'); 
+3

这听起来像jsperf工作。是?没有? – Nenotlep 2013-11-21 11:16:03

回答

75

区别在于,当您将文档片段添加到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 
+3

感谢您的回复。你说它允许同时插入多个,但我可以使用doc.createElement来实现。唯一的区别是我必须首先将元素包装在标记中,然后将插入到DOM中。这就是为什么我应该使用createDocumentFragment?为了避免不必要的元素被插入到DOM中? – screenm0nkey 2010-08-03 15:36:47

+3

是的,这绝对是使用它的一个原因。另外,文档片段可以包含任何类型的节点,而元素可以不包含。 – 2010-08-03 15:58:49

+3

其实片段不会“消失”;浏览器将其childNodes移动到DOM。所以片段仍然存在,但插入后它将是空的。 – inf3rno 2014-08-03 11:40:13

4

创建元素和文档片段之间的另一个很重要的区别:当您创建一个元素和追加

它到DOM,元素被附加到DOM,以及孩子。

使用文档片段,仅附加子项。

取的情况下:

var ul = document.getElementById("ul_test"); 
 

 

 
// First. add a document fragment: 
 

 

 
(function() { 
 
    var frag = document.createDocumentFragment(); 
 
    
 
    
 
    var li = document.createElement("li"); 
 
    li.appendChild(document.createTextNode("Document Fragment")); 
 
    frag.appendChild(li); 
 
    
 
    ul.appendChild(frag); 
 
    console.log(2); 
 
}()); 
 

 
(function() { 
 
    var div = document.createElement("div"); 
 
    
 
    
 
    var li = document.createElement("li"); 
 
    li.appendChild(document.createTextNode("Inside Div")); 
 
    div.appendChild(li); 
 
    
 
    ul.appendChild(div); 
 
}());
Sample List: 
 
<ul id="ul_test"></ul>

导致这种畸形的HTML(加空格)

<ul id="ul_test"> 
    <li>Document Fragment</li> 
    <div><li>Inside Div</li></div> 
</ul> 
相关问题