Вопрос

У меня функция, которая принимает объект в качестве параметра, и использует структуру объекта для создания узлов вложенных DOM, но я получаю следующую ошибку:

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.

То, что я хотел бы, чтобы моя функция, если прилагается с подходящим объектом в качестве параметра, пример:

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

Это создало бы следующие узлы DOM:

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

Вот моя попытка до сих пор:

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

Я уже борюсь!

В идеале я хотел бы в конечном итоге добавить больше детского ключа на каждый объект, а не только tag, но также id, innerHTML, class и т.п.

Любой Хэл будет очень признателен, хотя, пожалуйста: я уверен Рамки или библиотека мог сделать это для меня всего за несколько строк кода, или что-то подобное, но Я бы предпочел не использовать один Для этого конкретного проекта.

Если бы вы могли кратко объяснить свои ответы, это действительно помогло мне узнать, как это все работает, а где я пошел не так!

Спасибо!

NB: Я изменился и пометил линию в моей функции, о котором говорится сообщение об ошибке.

Я изменил это из:

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

к:

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

Это потому, что я хочу, чтобы любые вложенные ключи в детском объекте также будут созданы, так screen_name У детского ключа они тоже будут созданы. Извиняюсь, Надеюсь, вы можете понять это!

Я смотрю на http://jsperf.com/create-nested-dom-structure. Для некоторых указателей это может помочь вам тоже!

Это было полезно?

Решение

Ваша функция «Создание» должна быть написана рекурсивно.

Чтобы создать узел из ваших данных (в целом), вам нужно:

  1. Найдите свойство «тега» и создайте новый элемент
  2. Дайте элемент «ID» значение элемента (взято из данных)
  3. Для каждого элемента в «детях», сделайте узел и добавьте его

Таким образом:

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

Это вернет массив элементов документов, созданных из исходной «спецификации» объекта. Таким образом, из вашего примера вы позвоните:

var createdNodes = create(nodes);

и «созданныеноды» будут массивом одного элемента, <article> Тег с идентификатором "твиты". Этот элемент будет иметь два детей, <h2> Тег с идентификатором "Screen_name" и <p> Тег с идентификатором "текстом". (Теперь, когда я думаю об этом, вы можете пропустить задание «ID», если узел описание не имеет явного «идентификатора» или что-то еще.)

Таким образом, если у вас есть <div> На вашей странице под названием «Tweets» (чтобы использовать ваш пример, хотя, если, да, если вам определенно вы должны выбрать «ID» настроить часть моей функции), вы бы добавили такие результаты:

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

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

Другие советы

Я добавил функцию приложения, который принимает список элементов и контейнера для добавления к. Я удалил приложение к «Tweath», из-за функции создания, чтобы более эффективно отделить ваш код.

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

Здание на предыдущем ответе: я думаю, что вам все еще нужно создать элемент, который вы пытаетесь добавить:

tmp.appendChild (дети [опоры] .tag);

должно быть

TMP.appendChild (Document.Createlement (дети [опоры] .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);  
    };  
};
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top