Question

I ai une fonction qui prend un objet en tant que paramètre, et utilise la structure de l'objet à créer des noeuds DOM imbriqués, mais je reçois l'erreur suivante:

http://new.app/:75NOT_FOUND_ERR: DOM Exception 8: An attempt was made to reference a Node in a context where it does not exist.

Ce que je voudrais que ma fonction à faire, est, lorsqu'il est fourni avec un objet approprié comme paramètre, par exemple:

var nodes = {
    tweet: {
        children: {
            screen_name: {
                tag: "h2"
            },
            text: {
                tag: "p"
            }
        },
        tag: "article"
    }
};

Il créerait les noeuds DOM suivants:

<article>
    <h2></h2>
    <p></p>
</article>

Voici ma tentative à ce jour:

function create(obj) {
    for(i in obj){  
        var tmp = document.createElement(obj[i].tag);  
        if(obj[i].children) {  
            tmp.appendChild(create(obj[i].children)); /* error */
        }; 
        document.getElementById("tweets").appendChild(tmp);  
    };  
};

Je suis déjà aux prises!

Idéalement, je voudrais éventuellement ajouter la clé de l'enfant de chaque objet, non seulement tag, mais aussi id, innerHTML, class etc.

Tout hel serait très apprécié, mais s'il vous plaît: Je suis sûr un cadre ou à la bibliothèque pourrait faire cela pour moi en seulement quelques lignes de code, ou quelque chose de similaire, mais I « d préfère ne pas utiliser un pour ce projet particulier.

Si vous pouviez expliquer brièvement vos réponses aussi que ça m'a vraiment aider à apprendre comment tout cela fonctionne, et où je suis allé mal!

Merci!

NB: Je l'ai changé et a marqué la ligne dans ma fonction que le message d'erreur parle de

.

Je l'ai changé à partir de:

mp.appendChild(obj[i].children);

à:

mp.appendChild(create(obj[i].children));

Ceci est parce que je veux toutes les clés imbriquées dans les enfants objet aussi être créé, si screen_name avait une clé pour les enfants, ils seraient également créés. Désolé , je l'espère, vous pouvez comprendre!

Je regarde http://jsperf.com/create-nested-dom-structure pour quelques conseils, cela peut vous aider!

Était-ce utile?

La solution

Votre « créer » la fonction va être écrit de manière récursive.

Pour créer un noeud à partir de vos données (en général), vous devez:

  1. Trouvez la propriété « tag » et créer un nouvel élément
  2. donner à l'élément la valeur « id » de l'élément (pris à partir des données)
  3. Pour chaque élément « enfants », faire un nœud et l'ajouter

Ainsi:

function create(elementDescription) {
  var nodes = [];
  for (var n in elementDescription) {
    if (!elementDescription.hasOwnProperty(n)) continue;
    var elem = elementDescription[n];
    var node = document.createElement(elem.tag);
    node.id = n; // optional step
    var cnodes = create(elem.children);
    for (var c = 0; c < cnodes.length; ++c)
      node.appendChild(cnodes[c]);
    nodes.push(node);
  }
  return nodes;
}

Cela renvoie un tableau d'éléments de documents créés à partir de l'objet « spécification » d'origine. Ainsi, à partir de votre exemple, vous appelez:

var createdNodes = create(nodes);

et « createdNodes » serait un tableau d'un élément, une balise <article> avec id « tweets ». Cet élément aurait deux enfants, une étiquette <h2> avec id « screen_name » et une étiquette de <p> avec id « texte ». (Maintenant que je pense, vous pouvez sauter l'affectation « id » à moins que la description du noeud a une entrée explicite « id », ou quelque chose.)

Ainsi, si vous avez un <div> dans votre page appelée « tweets » (pour utiliser votre exemple, mais si donc vous voudriez certainement découper le paramètre « id » partie de ma fonction), vous ajouteriez les résultats comme ceci:

var createdNodes = create(nodes), tweets = document.getElementById('tweets');

for (var eindex = 0; eindex < createdNodes.length; ++eindex)
  tweets.appendChild(createdNodes[eindex]);

Autres conseils

I ajouté un appendList de fonction qui accepte une liste d'éléments, et le récipient à ajouter à. J'ai enlevé le append à « tweets » partie de la fonction créer pour séparer plus efficacement votre code.

function create(obj) {
    var els = [];
    for(i in obj){  
        var tmp = document.createElement(obj[i].tag);  
        var children;
        if(children = obj[i].children) {  
            var childEls = create(children);
            appendList(childEls, tmp);
        }
        els.push(tmp);
    }; 
    return els;
};
function appendList(list, container){
    for(var i = 0, el; el = list[i]; i++){
        container.appendChild(el);
    }
};
// gets an array of root elements populated with children
var els = create(nodes); 
// appends the array to "tweets"
appendList(els, document.getElementById("tweets")); 

Miser sur la réponse précédente: Je pense que vous avez encore besoin de créer l'élément que vous essayez d'ajouter:

  

tmp.appendChild (enfants [prop] .tag);

doit être

  

tmp.appendChild (document.createElement (enfants [prop] .tag));

function create(obj) {
    for(i in obj){  
        var tmp = document.createElement(obj[i].tag);  
        var children;
        if(children = obj[i].children) {  
            for(var prop in children)
                tmp.appendChild(document.createElement(children[prop].tag));   
        }
        document.getElementById("tweets").appendChild(tmp);  
    };  
};
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top