Czy powinienem użyć dokumentu.createDocumentFragment lub document.createElement

Czytałam o fragmentach dokumentu i reflow DOM i zastanawiałam się, jak document.createDocumentFragment różni się od document.createElement, ponieważ wygląda na to, że żaden z nich nie istnieje w DOM, dopóki nie dołączę ich do elementu DOM.

Zrobiłem test (poniżej) i wszystkie zajęły dokładnie tyle samo czasu (około 95ms). Domyślam się, że może to być spowodowane brakiem stylu zastosowanego do żadnego z elementów, więc może nie ma reflow.

W każdym razie, na podstawie poniższego przykładu, dlaczego powinienem używać createDocumentFragment zamiast z createElement podczas wstawiania do DOM i jaka jest różnica między nimi.

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');
Author: Brock Adams, 2010-08-03

2 answers

Różnica polega na tym, że fragment dokumentu skutecznie znika po dodaniu go do DOM. Dzieje się tak, że wszystkie węzły podrzędne fragmentu dokumentu są wstawiane w miejscu w DOM, w którym wstawiany jest fragment dokumentu, a sam fragment dokumentu nie jest wstawiany. Sam fragment nadal istnieje, ale teraz nie ma dzieci.

Pozwala to na wstawianie wielu węzłów do DOM w tym samym czasie:

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
 83
Author: Tim Down,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-03 13:39:14

Kolejna bardzo ważna różnica między tworzeniem elementu a fragmentem dokumentu:

Kiedy tworzysz element i dołączasz go do DOM, element jest dołączany do DOM, a także do dzieci.

Z fragmentem dokumentu dołączane są tylko dzieci.

Weźmy przypadek:

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>

Co skutkuje nieprawidłowym uformowaniem HTML (dodano białe znaki)

<ul id="ul_test">
  <li>Document Fragment</li>
  <div><li>Inside Div</li></div>
</ul>
 5
Author: Jeremy J Starcher,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-14 00:20:21