2016-10-02 1 views
2

j'obtenir une copie active d'un HTML5 <template> en utilisant la fonction importNode():appendChild() supprime le contenu du modèle importé

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

Après cela, je remplis les données dynamiques,

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

et enfin, J'ajoute le noeud dans le conteneur cible:

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

Mon problème: le noeud result a tout son contenu supprimé: je ne peux pas accéder aux éléments de composant du modèle dans le noeud de résultat. En fait, le nœud result ne contient aucun nœud enfant une fois que l'opération appendChild a été effectuée.

Je pense que la valeur de retour de appendChild doit pointer vers le noeud qui a été inséré dans le conteneur et qui fait maintenant partie du document actif. Toute explication pourquoi ce n'est pas le cas?

Voici le jsFiddle (testé dans Chrome 53):

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

+0

Si jquery disponible, utilisez 'clone()' – Turtle

+2

@TurtIe Je travaille avec le célèbre cadre « Vanilla JS » (0 Octets de téléchargement) :-) je peux obtenir ce que je dois en inspectant le récipient après la ' opération appendChild'. Je veux juste savoir pourquoi je ne peux pas inspecter la valeur de retour d'appendChild. – rplantiko

Répondre

2

Il est dû au fait que vous ne manipule pas un Node mais DocumentFragment.

Si vous souhaitez obtenir le nombre de nœuds insérés, vous devez effectuer l'appel sur le conteneur parent (c dans votre exemple), puis vous obtiendrez la bonne réponse (5).

Mais vous voulez compter que les éléments de l'enfant que vous avez ajouté, vous ne devriez pas utiliser childNodes, mais la propriété de l'interface ParentNode children:

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

Après avoir été ajouté au récipient c, DocumentFragment t n'a plus d'enfants.

De l'MDN documentation:

Diverses autres méthodes peuvent prendre un fragment de document comme un argument (par exemple, les méthodes d'interface de noeud tels que Node.appendChild et Node.insertBefore), auquel cas les enfants du fragment sont ajouté ou inséré à l'emplacement dans le DOM où vous insérez le fragment de document , pas le fragment lui-même. Le fragment lui-même continue d'exister (en mémoire) mais n'a plus aucun enfant.

Le DOM 3 W3C recommendation est également clair:

En outre, diverses opérations - telles que l'insertion des noeuds que les enfants d'un autre nœud - peut prendre des objets DocumentFragment comme arguments; cela entraîne tous les nœuds enfants du DocumentFragment étant déplacé à la liste des enfants de ce nœud.

+1

Oui, 't' est un fragment de document. Mais avant d'exécuter l'instruction 'c.appendChild (t)', il * a * children - ensuite il est vide, comme le 'result' de l'opération. Pourquoi ça change? Ce devrait être une référence à un seul et même fragment, avec le même contenu qu'auparavant - pas un nœud de fragment de document vide. – rplantiko

+0

Il change qu'un DocumentFragment n'agisse pas en tant que Node car ce n'est pas un Node, donc vous ne pouvez pas vous attendre à avoir le comportement de quelque chose qu'il n'est pas. J'ai ajouté une citation du doc ​​et spec. – Supersharp

+0

Merci! C'est donc un "cas de travail comme prévu". – rplantiko