从 javascript 节点对象生成无序列表
我编写了以下代码,这些代码的目的是从一些javascript Node对象生成一个
:<html>
<body>
<div id='content'></div>
<script type='text/javascript'>
function node(name,parent){
this.name=name;
this.parent=parent;
this.level=function(){
if(this.parent==null)
return 0;
return this.parent.level()+1;
}
this.childs=new Array();
}
//create a rootNode, having no parent
var rootNode=new node('AAA',null);
//create node1 and add it to the child of rootNode
var node1=new node('BBB',rootNode);
rootNode.childs.push(node1);
//create node2 and add it to the child of rootNode
var node2=new node('CCC',rootNode);
rootNode.childs.push(node2);
//create node3 and add it to the child of node1
var node3=new node('DDD',node1);
node1.childs.push(node3);
//create node4 and add it to the child of node1
var node4=new node('EEE',node1);
node1.childs.push(node4);
//create node5 and add it to the child of node2
var node5=new node('FFF',node2);
node2.childs.push(node5);
function getTreeHTML(node,html){
if(node.level()==0)
html+='<ul>';
html+='<li>';
html+=node.name;
if(node.childs.length > 0){
html+='<ul>';
for(var i in node.childs){
html+=getTreeHTML(node.childs[i],html);
}
html+='</ul>';
}
html+='</li>';
if(node.level()==0)
html+='</ul>';
return html;
}
var treeHTML=getTreeHTML(rootNode,'');
document.getElementById('content').innerHTML=treeHTML;
</script>
</body>
</html>
在 rootNode 下,有两个直接子节点,对于这两个子节点,一个其中一个应该有两个 childs 孩子,另一个应该有一个孩子。我怀疑 getTreeHTML()
函数中存在逻辑错误,但我无法弄清楚它是什么,请随意将代码粘贴到 http://htmledit.squarefree.com/,那么你就可以很快明白我的意思。
非常感谢大家。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
问题就在这里:
您最终添加到 HTML 字符串两次,因为在函数中您附加到传入的 HTML 字符串,但随后您也对其返回的内容使用附加操作。如果您将其更改为其中任何一个,它都可以正常工作:
离题:如果您感兴趣的话,一些建议/推荐/观察;以下内容并不重要,只是有帮助:
join('')
,而不是连接字符串,通常会更快完成后将它们全部组合成一根绳子。node
这样的构造函数最初被限制(Node
),以将它们与非构造函数区分开来。您的每个
node
对象都会获得其自己的level
函数的副本,这在您的代码中不是必需的。他们都可以共享一个级别
功能,如下所示:在英语中,“child”的复数是“children”(不规则)。
for..in
循环遍历数组索引,就像在for(var i in node.childs){
中一样,是很微妙的,而且在技术上是不正确的,除非您采取了一些循环中的预防措施;如果你对数组做任何有趣的事情,比如向它们添加更多元数据(数组只是对象,你可以向它们添加任意属性;库有时会向 Array.prototype 添加属性来消除浏览器差异,这会搞乱一个简单的for..in
循环)。详细信息请参见:的神话与现实for..in
this.childs=new Array();
编写为this.childs=[];
如果你喜欢;它们具有完全相同的效果。无论您将
var
语句放在代码中的什么位置,它都会在函数顶部(或全局作用域的顶部,如果var
是全球性的)。我认为我在这方面有点靠自己,但我不喜欢我的代码对代码维护者有一点误导,所以我总是把var
放在最上面。更多内容请参见糟糕的误解var
。例如:推荐
node
上的一个函数,该函数创建一个子节点并将其挂起,这样就可以避免设置parent
但随后添加子节点的可能性到错误的childs
数组(或者根本没有添加)。null
表示“没有父级”很好,但undefined
实际上更容易使用。if
语句完全没问题,但我认为值得一提,因为这是常见的做法。将所有这些和一些小事情放在一起:
The problem is here:
You're ending up adding to the HTML string twice, because within the function you append to the HTML string passed in, but then you use an append operation with what it returns as well. If you change it to either of these, it works fine:
Off-topic: Some suggestions/recommendations/observations if you're interested; none of the below is meant to be critical, only helpful:
join('')
to put them all together into one string when you're done.node
initially capped (Node
), to differentiate them from non-constructor functions.Each of your
node
objects will get its own copy of thelevel
function, which isn't necessary in your code. They can all share onelevel
function, like this:In English, the plural of "child" is "children" (it's irregular).
for..in
to loop through array indexes, as in yourfor(var i in node.childs){
, is delicate and technically incorrect unless you take a couple of precautions in the loop; it will fail if you do anything interesting with your arrays like add more meta-data to them (arrays are just objects, you can add arbitrary properties to them; and libraries sometimes add properties toArray.prototype
to smooth out browser differences, which will muck up a naivefor..in
loop). Details here: Myths and realities offor..in
this.childs=new Array();
asthis.childs=[];
if you like; they have exactly the same effect.Regardless of where you put your
var
statement in your code, it takes effect at the top of the function (or the top of the global scope, if thevar
is global). I think I'm a bit on my own with this, but I don't like having my code be a bit misleading to code maintainers, so I always put thevar
s up top. More here Poor misunderstoodvar
. So for instance:Recommend a function on
node
that creates a child and hooks it up, so you avoid the possibility of theparent
being set but then the child added to the wrongchilds
array (or not added at all).null
to mean "no parent" is fine, butundefined
is actually a bit easier to work with.if
statements are totally fine, but I thought it worth mentioning because it's such common practice.Taking all of that and a couple of minor things together:
一起删除
html
参数:Remove the
html
parameter all together: