Why is DocumentFragment cleared after appending
Asked Answered
D

1

7

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>
Development answered 30/3, 2015 at 17:57 Comment(0)
V
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);
Vivianaviviane answered 30/3, 2015 at 18:5 Comment(6)
Well, it still returns the same result…Development
@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.Vivianaviviane
I think you shouldn't use the term "copy" here. Either they are "moved" or "cloned".Zicarelli
Isn't there some clean method to simply get a reference to the newly appent node? I am a little bit surprised…Development
@Lithy, this is why jQuery is such a popular library.Vivianaviviane
@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.)Leftward

© 2022 - 2024 — McMap. All rights reserved.