从javascript节点对象生成无序列表

时间:2010-12-31 08:39:46

标签: javascript tree

我编写了以下代码,这些代码的目的是从一些javascript Node对象生成<ul>

<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/上,然后您可以快速查看我的意思。 / p>

非常感谢大家。

2 个答案:

答案 0 :(得分:4)

问题在于:

html+=getTreeHTML(node.childs[i],html);

你最终将HTML字符串添加到两次,因为在函数中你附加到传入的HTML字符串,但是你也使用了追加操作。如果你把它改成其中任何一个,它都可以正常工作:

html=getTreeHTML(node.childs[i],html);
html+=getTreeHTML(node.childs[i],'');

非主题:如果您感兴趣,可以提供一些建议/建议/意见;以下都不是重要的,只是有用的:

  1. 如果你在一个数组中构建了一串字符串,然后在完成后使用join('')将它们全部放在一个字符串中,它通常可以更快地连接字符串。
  2. 标准练习(您可以自由忽略!)是使node之类的构造函数最初加盖(Node),以区别于非构造函数。
  3. 每个node对象都会获得level函数的副本,这在您的代码中是不必要的。他们都可以共享一个 level功能,如下所示:

    function node(name,parent){
        this.name=name;
        this.parent=parent;
        this.childs=new Array();
    }
    node.prototype.level = function() {
        if(this.parent==null)
            return 0;
        return this.parent.level()+1;                    
    }
    
  4. 在英语中,“孩子”的复数是“孩子”(不规则)。

  5. 使用for..in循环遍历数组索引,就像在for(var i in node.childs){中一样,除非你在循环中采取一些预防措施,否则在技术上是不正确的。如果你对你的数组做任何有趣的事情就会失败,比如向它们添加更多元数据(数组只是对象,你可以为它们添加任意属性;库有时会向Array.prototype添加属性以消除浏览器差异,这会破坏一个天真的for..in循环。详情请见Myths and realities of for..in
  6. 如果您愿意,可以将this.childs=new Array();写为this.childs=[];;它们具有完全相同的效果。
  7. 无论您将var语句放在代码中的哪个位置,它都会在函数顶部生效(如果var是全局的,则在全局范围的顶部生效) 。我认为我对此有点自负,但我不喜欢让我的代码对代码维护者有点误导,所以我总是把var放在首位。更多Poor misunderstood var。例如:

    // This series of statements
    doSomething();
    doSomethingElse();
    var a = new Foo();
    doAnotherThing();
    
    
    // ...is *exactly* identical to:
    var a;
    doSomething();
    doSomethingElse();
    a = new Foo();
    doAnotherThing();
    
  8. node上推荐一个创建子项的函数并将其挂钩,这样就可以避免设置parent的可能性,但是孩子会添加错误childs }数组(或根本没有添加)。

  9. 使用null表示“没有父母”是正常的,但undefined实际上更容易使用。
  10. 您可以在某些地方使用JavaScript's Curiously-Powerful OR Operator (||)的力量。您在JavaScript代码中看到 lot if语句完全很好,但我认为值得一提,因为这是常见的做法。
  11. 大括号真的是你的朋友,即使他们没有必要。
  12. 把所有这些和一些小事放在一起:

    var rootNode, node1, node2;
    
    function Node(name, parent){
        this.name = name;
        this.parent = parent; // undefined if none
        this.children = [];
    }
    Node.prototype.level = function(){
        return this.parent ? this.parent.level() + 1 : 0;
    };
    Node.prototype.addChild = function(name) {
        var child;
    
        child = new Node(name, this);
        this.children.push(child);
        return child;
    };
    
    //create a rootNode, having no parent
    rootNode = new Node('AAA');
    
    //create node1 and add it to the child of rootNode
    node1 = rootNode.addChild('BBB');
    
    //create node2 and add it to the child of rootNode
    node2 = rootNode.addChild('CCC');
    
    //create node3 and add it to the child of node1
    node1.addChild('DDD');
    
    //create node4 and add it to the child of node1
    node1.addChild('EEE');
    
    //create node5 and add it to the child of node2
    node2.addChild('FFF');
    
    function getTreeHTML(node, html) {
        var i;
    
        html = html || []; // In case they don't give it
    
        if(node.level()==0) {
            html.push('<ul>');
        }
    
        html.push('<li>');
        html.push(node.name);
        if (node.children.length > 0) {
            html.push('<ul>');
            for (i = 0; i < node.children.length; ++i) {
                getTreeHTML(node.children[i], html);
            }
            html.push('</ul>');
        }
        html.push('</li>');
    
        if (node.level() == 0) {
            html.push('</ul>');
        }
    
        return html;
    }
    
    var treeHTML = getTreeHTML(rootNode).join('');
    document.getElementById('content').innerHTML=treeHTML;
    

答案 1 :(得分:1)

一起删除html参数:

function getTreeHTML(node){
    var 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+='</ul>';
    }
    html+='</li>';

    if(node.level()==0)
        html+='</ul>';
    return html;
}
相关问题