js树状图的无限递归问题

有如下html结构

.tree {
    background: #eee;
}

.tree_dir {
    line-height: 1.67;
}

.dir_title {
    font-weight: 700;
    margin-bottom: .72em;
    cursor: pointer;
}

.tree_dir .dir_title {
    margin-left: 1em;
}

.dir_children {
    margin-left: 1em;
    border-left: 1px dotted #000;
    display: none;
}

.dir_title.open + .dir_children {
    display: block;
}

/*.dir > .dir_children{
            margin-left: 0;
        }*/
.dir_children_file {
    margin-left: 1em;
    margin-bottom: .72em;
    display: block;
}
<div class="tree">
    <div class="tree_dir">
        <div class="dir_title open">level1</div>
        <div class="dir_children">
            <a href="http://baidu.com" class="dir_children_file">百度</a>
            <a href="http://qq.com" class="dir_children_file">QQ</a>
            <a href="http://sina.com.cn" class="dir_children_file">sina</a>
            <a href="http://163.com" class="dir_children_file">163</a>
            <div class="dir_title open">level2</div>
            <div class="dir_children">
                <a href="http://baidu.com" class="dir_children_file">百度</a>
                <a href="http://qq.com" class="dir_children_file">QQ</a>
                <a href="http://sina.com.cn" class="dir_children_file">sina</a>
                <a href="http://163.com" class="dir_children_file">163</a>
                <div class="dir_title open">level3</div>
                <div class="dir_children">
                    <a href="http://baidu.com" class="dir_children_file">百度</a>
                    <a href="http://qq.com" class="dir_children_file">QQ</a>
                    <a href="http://sina.com.cn" class="dir_children_file">sina</a>
                    <a href="http://163.com" class="dir_children_file">163</a>
                </div>
            </div>
        </div>
    </div>
</div>
<div class="tree" id="tree"></div>

和这样的 data 数据

var data = [{
    level1: {
        "百度": "http://baidu.com",
        "QQ": "http://qq.com",
        "sina": "http://sina.com.cn",
        "163": "http://163.com",
        level2: {
            "百度": "http://baidu.com",
            "QQ": "http://qq.com",
            "sina": "http://sina.com.cn",
            "163": "http://163.com",
            level3: {
                "百度": "http://baidu.com",
                "QQ": "http://qq.com",
                "sina": "http://sina.com.cn",
                "163": "http://163.com"
            }
        }
    }
}];

我写了一点点 js 代码然后被卡住了

// 菜鸟代码 请无视。。。
function Tree(selector, data) {
    this.el = document.querySelector(selector);
    // 遍历数组
    for (var i = 0; i < data.length; i++) {
        var dirData = data[i],
            ctn = document.createElement('div');
        ctn.className = 'tree_dir';
        for (var x in dirData) {
            // 不会写了
            if(typeof dirData[x] === 'object'){
            }
        }
        this.el.appendChild(ctn);
    }
    function _f(){}
}
new Tree('#tree', data);

怎么封装成一个 js 函数,以便传入一个规定格式的 data 数据生成 html。
我已经被递归绕晕了。求解。


【更新】谢谢大家的回答,我才发现 data 不应该是数组,而应该是

var data = {
    level1: { // 第一个顶级
        "百度": "http://baidu.com",
        "QQ": "http://qq.com",
        "sina": "http://sina.com.cn",
        "163": "http://163.com",
        level2: {
            "百度": "http://baidu.com",
            "QQ": "http://qq.com",
            "sina": "http://sina.com.cn",
            "163": "http://163.com",
            level3: {
                "百度": "http://baidu.com",
                "QQ": "http://qq.com",
                "sina": "http://sina.com.cn",
                "163": "http://163.com"
            }
        }
    },
    siblingsLevel1: { // 第二个顶级
        ...
        level2:...
    }
};

这样就应该在同一个 .tree 下面生成两个 .tree_dir

<div class="tree">
  <div class="tree_dir">...</div>
  <div class="tree_dir">...</div>
</div>

[已解决]谢谢各位帮助。
http://jsfiddle.net/shannon9/Lhhfx8dm/embedded/

阅读 4.5k
5 个回答

function Tree(selector, data) {

this.el = document.querySelector(selector);
for (var i = 0; i < data.length; i++) {
    var dirData = data[i],
    ctn = document.createElement('div');
    ctn.className = 'tree_dir';
    for(var x in data){
        for(var j in data[x]){
            if(typeof data[x][j] === 'object'){
                _obj(j,data[x][j],ctn)
            }
        }
    }
    this.el.appendChild(ctn);
}
function getData(data,par){
    var divchild =  document.createElement('div');
        divchild.className = 'dir_children';
        par.appendChild(divchild)
    for (var x in data) {
        if(typeof data[x] === 'string'){
            _str(x,data[x],divchild)
        }
        if(typeof data[x] === 'object'){
            _obj(x,data[x],divchild)
        }
    }
}
function _str(name,href,par){
    var str_a = document.createElement('a');
    str_a.className = 'dir_children_file';
    str_a.innerHTML = name;
    str_a.setAttribute('href',href)
    par.appendChild(str_a)
}
function _obj(name,obj,par){
    var outside = document.createElement('div');
    outside.className = 'dir_title open';
     outside.innerHTML = name;
     par.appendChild(outside)
     getData(obj,par)
}

}
new Tree('#tree', data);

这个跟递归没有什么关系吧。

你的目的:
传入数据 -》 解析数据 -》 生成html
你需要做的

分析数据 -》 分析数据元素 -》 根据不同的元素生成不同的html块代码

没有需要递归的地方

用组件递归,

代码很烂,做个参考:

function Tree(selector, data){
    var ss = function(item){
        var html = '';
        for(var key in item){
            html += '<div class="tree_dir"><div class="dir_title open">'+key+'</div>';
            
            var sb = item[key],
                j = '',
                _s = {};
            for(var i in sb){
                if( i.indexOf('level')==-1 ){
                    html += '<a href="'+ sb[i] +'" class="dir_children_file">'+ i +'</a>';
                }else{
                    j = i;
                }
            }
            if( j ){
                var _s = {};
                _s[j] = sb[j];
                html += ss( _s );
            }

            html += '</div>';
        }
        
        return html;
    }

    var html = '';
    for(var i=0, len=data.length; i<len; i++){
        html += ss( data[i] );
    }
    var el = document.querySelector(selector);
    el.innerHTML = html;
}

new Tree('.container', data);

数据结构为:

var data = [{
    level1: {
        "百度": "http://baidu.com",
        "QQ": "http://qq.com",
        "sina": "http://sina.com.cn",
        "163": "http://163.com",
        level2: {
            "百度": "http://baidu.com",
            "QQ": "http://qq.com",
            "sina": "http://sina.com.cn",
            "163": "http://163.com",
            level3: {
                "百度": "http://baidu.com",
                "QQ": "http://qq.com",
                "sina": "http://sina.com.cn",
                "163": "http://163.com"
            }
        }
    },
    level4: {
        "百度": "http://baidu.com",
        "QQ": "http://qq.com",
        "sina": "http://sina.com.cn",
        "163": "http://163.com",
        level5: {
            "百度": "http://baidu.com",
            "QQ": "http://qq.com",
            "sina": "http://sina.com.cn",
            "163": "http://163.com",
            level6: {
                "百度": "http://baidu.com",
                "QQ": "http://qq.com",
                "sina": "http://sina.com.cn",
                "163": "http://163.com",
                level7: {
                    "百度": "http://baidu.com",
                    "QQ": "http://qq.com",
                    "sina": "http://sina.com.cn",
                    "163": "http://163.com"
                }
            }
        }
    }
},
{
    level8: {
        "百度": "http://baidu.com",
        "QQ": "http://qq.com",
        "sina": "http://sina.com.cn",
        "163": "http://163.com"
    }
}];

产生的html为:
图片描述

楼主的问题,我也想问。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题