[英]trouble creating nested dom nodes in javascript
I've a function that takes an object as a parameter, and uses the structure of the object to create nested DOM nodes, but I receive the following error: 我有一个将对象作为参数的函数,并使用对象的结构来创建嵌套的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.
What I would like my function to do, is, when supplied with a suitable object as a parameter, example: 我希望函数执行的操作是,在将适当的对象作为参数提供时,例如:
var nodes = {
tweet: {
children: {
screen_name: {
tag: "h2"
},
text: {
tag: "p"
}
},
tag: "article"
}
};
It would create the following DOM nodes: 它将创建以下DOM节点:
<article>
<h2></h2>
<p></p>
</article>
Here is my attempt so far: 到目前为止,这是我的尝试:
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);
};
};
I'm already struggling! 我已经在挣扎了!
Ideally I'd like to eventually add more child key's to each object, not just tag
, but also id, innerHTML, class
etc. 理想情况下,我想最终为每个对象添加更多的子键,不仅是
tag
,还包括id, innerHTML, class
等。
Any hel would be much appreciated, though please: I'm sure a framework or library could do this for me in just a few lines of code, or something similar, but I'd prefer not to use one for this particular project. 不过,请您不胜感激:我敢肯定,只要几行代码或类似的代码, 框架或库就可以为我做到这一点,但是我不希望在特定项目中使用它 。
If you could briefly explain your answers too it'd really help me learn how this all works, and where I went wrong! 如果您也可以简短地解释您的答案,那将真的帮助我了解这一切的原理以及我出了什么问题!
Thank you! 谢谢!
NB: I've changed and marked the line in my function that the error message is talking about. 注意:我已经更改并标记了错误消息中正在谈论的函数中的行。
I changed it from: 我将其更改为:
mp.appendChild(obj[i].children);
to: 至:
mp.appendChild(create(obj[i].children));
This is because I want any nested keys in the children object to also be created, so screen_name
had a children key, they too would be created. 这是因为我希望在子对象中也创建任何嵌套键,所以
screen_name
有一个子键,它们也会被创建。 Sorry , I hope you can understand this! 对不起 ,希望您能理解!
I'm looking at http://jsperf.com/create-nested-dom-structure for some pointers, this may help you too! 我正在寻找一些指针的http://jsperf.com/create-nested-dom-structure ,这也可能对您有所帮助!
Your "create" function is going to have to be written recursively. 您的“创建”功能将必须递归编写。
To create a node from your data (in general), you need to: 要根据数据创建节点(通常),您需要:
Thus: 从而:
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;
}
That will return an array of document elements created from the original "specification" object. 这将返回从原始“规范”对象创建的文档元素数组。 Thus from your example, you'd call:
因此,从您的示例中,您可以调用:
var createdNodes = create(nodes);
and "createdNodes" would be an array of one element, an <article>
tag with id "tweets". 和“ createdNodes”将是一个元素的数组,一个ID为“ tweets”的
<article>
标签。 That element would have two children, an <h2>
tag with id "screen_name" and a <p>
tag with id "text". 该元素将有两个孩子,一个ID为“ screen_name”的
<h2>
标记和一个ID为“ text”的<p>
标记。 (Now that I think of it, you might want to skip the "id" assignment unless the node description has an explicit "id" entry, or something.) (现在我想到了,除非节点描述中有一个明确的“ id”条目或其他内容,否则您可能要跳过“ id”分配。)
Thus if you have a <div>
in your page called "tweets" (to use your example, though if so you'd definitely want to cut out the "id" setting part of my function), you'd add the results like this: 因此,如果您的页面中有一个名为“ tweets”的
<div>
(以您的示例为例,尽管如此,您肯定希望删除函数的“ id”设置部分),则需要添加如下结果这个:
var createdNodes = create(nodes), tweets = document.getElementById('tweets');
for (var eindex = 0; eindex < createdNodes.length; ++eindex)
tweets.appendChild(createdNodes[eindex]);
I added a function appendList that accepts a list of elements, and the container to append to. 我添加了一个函数appendList,它接受元素列表以及要附加到的容器。 I removed the append to "tweets" part out of the create function to more effectively separate your code.
我从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"));
Building on the previous answer: I think you still need to create the element you're trying to append: 基于先前的答案:我认为您仍然需要创建要添加的元素:
tmp.appendChild(children[prop].tag);
tmp.appendChild(儿童[丙] .TAG);
should be 应该
tmp.appendChild(document.createElement(children[prop].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.