我正在尝试制作一个可步行的DOM树,如下所示:
输入:
<div>
<span>Foo</span>
<span>Bar</span>
</div>
输出(类似Python的):
{'div': [{'span': 'Foo'},
{'span': 'Bar'}]}
我想像这样遍历它:
elements['div']['span']; // Output is "Foo".
我目前的代码是:
function createObject(element) {
var object = {};
if (element.childNodes.length > 0) {
for (var i = 0; i < element.childNodes.length; i++) {
object[element.tagName] = createObject(element.childNodes[i]);
}
return object;
} else {
return element.nodeValue;
}
}
但它不起作用(循环不运行)。任何人都可以帮忙解决这个问题吗?
答案 0 :(得分:0)
在没有尝试测试的情况下,看起来主要的问题是你的for ... in
循环 - 它在Python中与Javascript中的工作方式不同。
for (child in element.childnodes)
应该是一个基于迭代器的循环:
for (var x=0, child; x<element.childNodes.length; x++) {
child = element.childNodes[x];
// etc
}
您还将获得您不期望的文本节点,并应在递归之前检查child.nodeType != Node.TEXT_NODE
。
答案 1 :(得分:0)
看起来childNodes.length在浏览器之间有所不同,也许您应该使用hasChildNodes?
另外,您是否使用了firebug(或任何js调试器)来查看元素是否已正确填充?
编辑:我发现了什么问题。您无法创建对象的对象。相反,您必须创建对象数组。检查您是否有childNodes,如果没有,则创建一个对象。否则,创建一个数组。
就像你的类似python的输出显示: - )
答案 2 :(得分:0)
会发生什么?
If no child {name: value}
if childs {name: [
{childname: childvalue}
]}
遵循这个逻辑,这就是结果。注意应使用nodeName
代替tagName
。还选择了文本节点,其中nodeName
#Text . If you want to only select elements, add
if(element.childNodes [i] .nodeType == 1)`:
function createObject(element) {
var object, childs = element.childNodes;
if (childs.length > 0) {
object = [];
for (var i = 0; i < childs.length; i++) {
//Uncomment the code if you want to ignore non-elements
// if(childs.nodeType == 1) {
object.push(createObject(childs[i]));
// }
}
return object;
} else {
object = {};
object[element.nodeName] = element.nodeValue;
return object;
}
}