appendChild() 从导入的模板中剥离内容

appendChild() strips content from imported template

我使用函数 importNode():

获得了 HTML5 <template> 的活动副本
  function getTemplate() {
    var t = document.getElementById("example");
    return document.importNode(t.content,true);
  }

在此之后,我填充动态数据,

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

最后,我将节点附加到目标容器中:

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

我的问题:result 节点的所有内容都被剥离了:我无法在结果节点中访问模板的组件元素。实际上,result 节点在执行 appendChild 操作后根本不包含任何子节点。

我希望 appendChild 的 return 值应该指向已插入到容器中并且现在是活动文档的一部分的节点。任何解释为什么不是这种情况?

这是 jsfiddle(在 Chrome 53 中测试过):

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

这是因为你操作的不是Node而是DocumentFragment

如果你想获得插入的节点数,你应该在父容器上执行调用(c 在你的例子中)然后你会得到正确的答案(5)。

但是如果你只想统计你添加的子元素,你不应该使用childNodes,而是ParentNode接口的属性 children:

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

添加到容器 c 后,DocumentFragment t 不再有子项。

来自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.

DOM 3 W3C recommendation也清楚:

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.