6

The first log returns a full li element while the second one returns an empty DocumentFragment. Why? I couldn't find any information about that behavior in any documentation.

var main = document.getElementById('main');
var fooTemplate = document.getElementById('my-template');
var foo = fooTemplate.content.cloneNode(true);

console.log(foo);
main.appendChild(foo);
console.log(foo);
<template id="my-template">
    <li>foo</li>
</template>

<ul id="main">
</ul>
Michael Haddad
  • 4,085
  • 7
  • 42
  • 82
Lithy
  • 817
  • 12
  • 23

1 Answers1

6

From the MDN docs on DocumentFragment

Various other methods can take a document fragment as an argument (e.g., any Node interface methods such as Node.appendChild and Node.insertBefore), in which case the children of the fragment are appended or inserted, not the fragment itself.

foo = fooTemplate.content.cloneNode(true) copies the document fragment to foo.

main.appendChild(foo) moves the contents of the foo document fragment into main. foo remains a document fragment, and all the nodes have moved so it's empty.

If you want to keep a reference to the DOM nodes after appending them, you need to store the childNodes, but if you just reference the nodeList, it'll be empty, so you'll need to convert it to an Array:

var nodes = Array.prototype.slice.call(foo.childNodes);
console.log(nodes);
main.appendChild(foo);
console.log(nodes);
zzzzBov
  • 174,988
  • 54
  • 320
  • 367
  • Well, it still returns the same result… – Lithy Mar 30 '15 at 20:32
  • 2
    @Lithy, oh, i see now. I spoke too soon. `fooTemplate.content.cloneNode(true)` clones the document fragment. Appending the document fragment moves the contents, leaving you with an empty document fragment. – zzzzBov Mar 30 '15 at 20:53
  • 1
    I think you shouldn't use the term "copy" here. Either they are "moved" or "cloned". – Bergi Mar 30 '15 at 23:19
  • 1
    Isn't there some clean method to simply get a reference to the newly appent node? I am a little bit surprised… – Lithy Mar 31 '15 at 07:30
  • @Lithy, this is why jQuery is such a popular library. – zzzzBov Mar 31 '15 at 13:34
  • @Lithy, If you used appendChild, you can actually get the last child from the node you appended it too. That's is pretty clean as you can put that stuff away in a function. Remember JS is single threaded, so it won't cause any problems. (Except for in NodeJs Maybe, but I'm not sure, and you won't be doing much DOM stuff there anyway.) – David Jul 06 '15 at 19:42