Search code examples
javascriptdomdocumentfragmenthtml5-template

appendChild() strips content from imported template


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/


Solution

  • 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.