Frage

Ich habe eine Funktion, die ein Objekt als Parameter übernimmt, und nutzt die Struktur des Objekts verschachtelten DOM-Knoten zu erstellen, aber ich erhalte die folgenden Fehler:

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.

Was würde ich meine Funktion gerne tut, ist, wenn sie mit einem geeigneten Objekt als Parameter geliefert, Beispiel:

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

Es würde den folgenden DOM-Knoten erstellen:

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

Hier ist mein Versuch so weit:

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);  
    };  
};

Ich kämpfe schon!

Im Idealfall würde ich schließlich gerne mehr Kind-Schlüssel der zu jedem Objekt hinzufügen, nicht nur tag, sondern auch id, innerHTML, class etc.

Jede hel wäre sehr willkommen, wenn Sie: Ich bin sicher, dass ein Rahmen oder Bibliothek könnte dies in nur wenigen Zeilen Code für mich tun, oder etwas Ähnliches, aber I ‚d lieber nicht eins verwenden für dieses Projekt.

Wenn Sie kurz Ihre Antworten erklären könnte, es würde wirklich helfen mir lernen, wie das alles funktioniert, und wo ich schief gelaufen ist!

Danke!

. NB: Ich habe mich verändert und die Zeile in meiner Funktion gekennzeichnet, dass die Fehlermeldung spricht

Habe ich es aus:

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

zu:

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

Das ist, weil ich alle verschachtelten Schlüssel in den Kindern will das Objekt auch erstellt werden, so screen_name einen Schlüssel Kinder hatten auch sie geschaffen würden. Es , ich hoffe, dass Sie das verstehen können!

Ich betrachte http://jsperf.com/create-nested-dom-structure für einige Hinweise, kann dies auch Ihnen helfen!

War es hilfreich?

Lösung

Ihre „create“ Funktion ist zu haben, rekursiv geschrieben werden.

einen Knoten aus Ihren Daten erstellen (in der Regel), müssen Sie:

  1. Finden Sie den "Tag" Eigenschaft und ein neues Element
  2. Geben Sie das Elemente den "id" Wert des Elements (aus den Daten entnommen)
  3. Für jedes Element in "Kinder", einen Knoten machen und fügen Sie es

So:

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;
}

Das wird eine Reihe von Dokumentenelementen Rückkehr aus dem ursprünglichen „Spezifikation“ Objekt erstellt. So aus Ihrem Beispiel, würden Sie rufen:

var createdNodes = create(nodes);

und "createdNodes" würde ein Array aus einem Element, ein <article> Tag mit der ID "tweets" sein. Dieses Element würde zwei Kinder hat, einen <h2>-Tag mit der ID "screen_name" und einem <p>-Tag mit der ID "Text". (Nun, da ich daran denke, mögen Sie vielleicht die „id“ Zuordnung überspringen, wenn die Knotenbeschreibung einen expliziten „id“ Eintrag hat, oder so etwas.)

Wenn Sie also eine <div> in Ihrer Seite mit dem Namen „Tweets“ haben (Ihr Beispiel zu verwenden, aber wenn so dass Sie auf jeden Fall wollen würden einen Teil meiner Funktion der „id“ auszuschneiden Einstellung), dann würden Sie die Ergebnisse hinzufügen wie folgt aus:

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

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

Andere Tipps

Ich habe eine Funktion appendList, die eine Liste von Elementen annimmt, und um den Behälter zu append zu. Ich entfernte das Anfügen auf „Tweets“ Teil der aus erstellen Funktion, um effektiven Code zu trennen.

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")); 

Auf der Grundlage der vorherigen Antwort: Ich denke, dass Sie immer noch das Element erstellen müssen Sie Append sind versuchen:

  

tmp.appendChild (Kinder [Prop] .tag);

sollte

  

tmp.appendChild (document.createElement (Kinder [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);  
    };  
};
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top