簡體   English   中英

在JavaScript中創建嵌套dom節點時遇到麻煩

[英]trouble creating nested dom nodes in javascript

我有一個將對象作為參數的函數,並使用對象的結構來創建嵌套的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等。

不過,請您不勝感激:我敢肯定,只要幾行代碼或類似的代碼, 框架或庫就可以為我做到這一點,但是我不希望在特定項目中使用它

如果您也可以簡短地解釋您的答案,那將真的幫助我了解這一切的原理以及我出了什么問題!

謝謝!

注意:我已經更改並標記了錯誤消息中正在談論的函數中的行。

我將其更改為:

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

和“ createdNodes”將是一個元素的數組,一個ID為“ tweets”的<article>標簽。 該元素將有兩個孩子,一個ID為“ screen_name”的<h2>標記和一個ID為“ text”的<p>標記。 (現在我想到了,除非節點描述中有一個明確的“ id”條目或其他內容,否則您可能要跳過“ id”分配。)

因此,如果您的頁面中有一個名為“ tweets”的<div> (以您的示例為例,盡管如此,您肯定希望刪除函數的“ id”設置部分),則需要添加如下結果這個:

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

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

我添加了一個函數appendList,它接受元素列表以及要附加到的容器。 我從create函數中刪除了“ tweets”部分的追加,以更有效地分離您的代碼。

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.createElement(兒童[丙] .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 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM