2

I obtain an active copy of an HTML5 <template> using function importNode():

  function getTemplate() {
    var t = document.getElementById("example");
    return document.importNode(t.content,true);
  }

After this, I fill the dynamic data,

  var t = fillTemplate({
    id:"test",
    text:"Enter test data"
  });

and finally, I append the node into the target container:

  var c = document.getElementById("container");
  var result = c.appendChild(t);

My problem: the result node has all its content stripped off: I can't access the component elements of the template in the result node. Actually, the result node contains no child nodes at all once the appendChild operation has been performed.

I expect that the return value of appendChild should point to the node that has been inserted into the container and which is now part of the active document. Any explanation why this is not the case?

Here is the jsfiddle (tested in Chrome 53):

https://jsfiddle.net/rplantiko/mv2rbhym/

Supersharp
  • 29,002
  • 9
  • 92
  • 134
rplantiko
  • 2,698
  • 1
  • 22
  • 21
  • If jquery available, use `clone()` – ch271828n Oct 02 '16 at 10:59
  • 2
    @TurtIe I work with the famous "Vanilla JS" framework (0 Bytes download) :-) I can get what I need by inspecting the container after the `appendChild` operation. I just want to know why I can't inspect appendChild's return value as well. – rplantiko Oct 02 '16 at 11:16

1 Answers1

2

It is due to the fact that you don't manipulate a Node but a DocumentFragment.

If you want get the number of Nodes inserted, you should perform the call on the parent container (c in your example) then you'll get the right answer (5).

But if you want to count only the child elements you added, you should not use childNodes, but the property of the ParentNode interface children:

c.childNodes.length  // = 5
c.children.length    // = 2

After being appended to the container c, the DocumentFragment t has no children any more.

From the MDN documentation:

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 at the location in the DOM where you insert the document fragment, not the fragment itself. The fragment itself continues to exist (in memory) but now has no children.

The DOM 3 W3C recommendation is also clear:

Furthermore, various operations -- such as inserting nodes as children of another Node -- may take DocumentFragment objects as arguments; this results in all the child nodes of the DocumentFragment being moved to the child list of this node.

Lonnie Best
  • 9,936
  • 10
  • 57
  • 97
Supersharp
  • 29,002
  • 9
  • 92
  • 134
  • 1
    Yes, `t` is a document fragment. But before performing the statement `c.appendChild(t)`, it *has* children - afterwards it is empty, like the `result` of the operation. Why does it change? It should be a reference to one and the same fragment, with the same content as before - not an empty document fragment node. – rplantiko Oct 03 '16 at 06:13
  • It changes that a DocumentFragment doesn't act as a Node because it's not a Node, so you can't expect to have the behaviour of something that it isn't. I've added a quote from the doc and spec. – Supersharp Oct 03 '16 at 12:15