10

I've searched through stackoverflow questions and found few questions about the same topic, but none of them has an extensive answer I'm looking for. Most answers are focused around performance, but I'm looking for other differences as well. Basically, this one sums up the question succinctly:

if I create an element (a for example) in a variable but DO NOT APPEND IT TO THE DOM, add elements (divs, tables, etc ) and stuff and after all the work has been done (loops, validations, styling of elements), that element is appended, is it the same as a fragment?

I've decided to give it a shot once again and see if anyone can give a good answer.

So, why would I want to use this:

var fragment = document.createDocumentFragment();
var divContainer = document.createElement("div");
var divHeader = document.createElement("div");
divContainer.appendChild( divHeader );
fragment.appendChild( divContainer );
document.getElementById("someElement").appendChild( fragment.cloneNode(true) );

instead of this:

var divContainer = document.createElement("div");
var divHeader = document.createElement("div");
divContainer.appendChild( divHeader );
document.getElementById("someElement").appendChild( divContainer );
Community
  • 1
  • 1
Max Koretskyi
  • 101,079
  • 60
  • 333
  • 488
  • 2
    @JamesThorpe, I've updated my questions with `Most answers are focused around performance, but I'm looking for other differences as well.` – Max Koretskyi Jul 04 '16 at 09:13
  • it's not the same since the fragment doesn't exist in the DOM, or I missed the question – caub Jul 04 '16 at 09:16
  • 1
    What is the question? What differences are you looking for? An element not added to the DOM is only a variable in memory and not rendered by the browser. What else do you want to know? – Esko Jul 04 '16 at 09:19
  • 1
    I think you should post your own question about the doubt you have. – Charlie Jul 04 '16 at 09:20
  • @CharlieH, updated the question – Max Koretskyi Jul 04 '16 at 09:29

1 Answers1

12

Both methods are largely the same, as they can both be used to store elements without modifying the DOM immediately. There are a few catches though.

Differences:

  • A div has the prototype chain HTMLDivElement - HTMLElement - Element - Node - EventTarget, whereas a document-fragment has DocumentFragment - Node - EventTarget. This means a div has more methods and properties available (like innerHTML).
  • When appending a div to the DOM, the whole element is inserted, the variable still references to the element. Appending a document-fragment inserts all its contents, leaving the variable to reference an empty fragment.

Usage document-fragment:

var fragment = document.createDocumentFragment();
var div1 = document.createElement('div');
var div2 = document.createElement('div');
var div3 = document.createElement('div');

fragment.appendChild(div1);
fragment.appendChild(div2);
div2.appendChild(div3);              //fragment now contains the sub-tree

document.body.appendChild(fragment); //fragment is now an empty document-fragment, and is not in the DOM.

Result:

<body>
    <div></div>       <!--div1-->
    <div>             <!--div2-->
         <div></div>  <!--div3-->
    </div>
</body>

Usage div:

var container = document.createElement('div');
var div1 = document.createElement('div');
var div2 = document.createElement('div');
var div3 = document.createElement('div');

container.appendChild(div1);
container.appendChild(div2);
div2.appendChild(div3);               //container is now a div with the sub-tree inside.

document.body.appendChild(container); //container is still the div with the sub-tree, but is now in the DOM.

Result:

<body>
    <div>                 <!--container-->
        <div></div>       <!--div1-->
        <div>             <!--div2-->
             <div></div>  <!--div3-->
        </div>
    </div>
</body>

In short:

  • Use an element if you only want to insert one element (with other elements inside it).
  • Use an element if you want to parse html in text format using innerHTML.
  • Use a document-fragment if you want to insert multiple adjacent elements.
Kevin Drost
  • 383
  • 4
  • 7
  • I think the question is more about speed. This applies to things like dynamically creating lists that require a list wrapper. If you just say `var ul = document.createElement('ul');` `for (i = 0; i < 10000; i++) { ul.appendChild(document.createElement('li')) }` `document.body.appendChild(ul)`, that should actually be minuscully better than creating frag, appending `li` to frag, appending frag to ul then finally appending ul to body. – cowbert Sep 29 '18 at 02:24
  • 2
    @cowbert, true. That's because you're only appending to the DOM _once_. It would be a different scenario when the `
      ` is already present in the DOM.
    – Kevin Drost Oct 03 '18 at 13:37
  • Perfect. Thank you for the answer. – felixy Dec 11 '18 at 14:25