javascript – 如何从JSON数据递归创建UL/LI – 多层深层

我试图使用以下 JSON数据在递归内部函数中创建以下类似的结构,运气不大,真的需要一些帮助,所以如果有人可以协助请做.先感谢您.
<ul>
    <li></li>
    <li>
        <a href=""></a>
        <div>
            <ul>
                <li>
                    <a href=""></a>
                    <div>
                         ....etc
                    </div>
                </li>
            </ul>
        </div>
    </li>
</ul>

我使用的JSON数据如下:

var JSON = {
    menu: [
        {id: '0',sub: [
            {name: 'lorem ipsum 0-0',link: '0-0',sub: null},{name: 'lorem ipsum 0-1',link: '0-1',{name: 'lorem ipsum 0-2',link: '0-2',sub: null}
            ]
        },{id: '1',{id: '2',sub: [
            {name: 'lorem ipsum 2-0',link: '2-0',{name: 'lorem ipsum 2-1',link: '2-1',{name: 'lorem ipsum 2-2',link: '2-2',sub: [
                {name: 'lorem ipsum 2-2-0',link: '2-2-0',{name: 'lorem ipsum 2-2-1',link: '2-2-1',{name: 'lorem ipsum 2-2-2',link: '2-2-2',{name: 'lorem ipsum 2-2-3',link: '2-2-3',{name: 'lorem ipsum 2-2-4',link: '2-2-4',{name: 'lorem ipsum 2-2-5',link: '2-2-5',{name: 'lorem ipsum 2-2-6',link: '2-2-6',sub: null}
            ]},{name: 'lorem ipsum 2-3',link: '2-3',{name: 'lorem ipsum 2-4',link: '2-4',{name: 'lorem ipsum 2-5',link: '2-5',{id: '3',sub: null}
    ]
}

我创建的代码(不完整,这是我需要帮助的脑筋急转弯)是:

$(function(){

    $.fn.dropdown = function(settings){
        var that = this;
        var settings = $.extend({},$.fn.dropdown.defaults,settings);
        var methods = {
            isArray: function(o){
                return Object.prototype.toString.call(o) === '[object Array]';
            },createDropdownCode: function(arr){
                var menu = arr.menu;
                var html = null;
                var menusort = function(menu){
                    html = that;

                    that.find("li").each(function(idx){

                        var menuList = menu[idx].sub;
                        var baseContainer = $(this);
                        var count = -1;

                        var subsort = (function(){

                            count += 1;

                            return function(submenu,pb){

                                var subblock;
                                subblock = $("<div />").append('<ul />');

                                if(methods.isArray(submenu)){

                                    for(var i=0;i<submenu.length;i++){

                                        var l = $("<li />").append("<a href='"+ submenu[i].link +"'>"+ submenu[i].name +"</a>");

                                        subblock.find('ul').append(l);

                                        if(pb !== undefined && i == submenu.length-1){
                                            pb.append(subblock)
                                        }

                                        if(methods.isArray(submenu[i].sub)){
                                            subsort(submenu[i].sub,subblock.find('ul li').eq(i));
                                        }

                                    }
                                }
                            }
                        })()
                        subsort(menuList)
                    })
                }
                menusort(menu);
                return null; //html !== null ? html.html() : null;
            },init: function(){

                // filter through json
                // create the div=>ul=>li
                if(settings.jsonData === undefined || settings.jsonData === null){
                    console.warn('No JSON Data passed')
                    return;
                }else{
                    if(!methods.isArray(settings.jsonData.menu)){
                        console.warn('No JSON Data passed')
                        return; // error,no data!
                    }
                }


                //var html = methods.createBlock(settings.jsonData.menu[0].sub);
                var html = methods.createDropdownCode(settings.jsonData);
                //console.log(html) 
            }
        }

        methods.init();

        return that;

    }

    $.fn.dropdown.defaults = {
        jsonData: null
    }

})

$('#menu').dropdown({
    jsonData: JSON
});

使用综合代码,感谢个人提供了足够接近的答案 – 虽然会研究其他人.

$.fn.dropdown = function(settings){

    var that = this;
    var settings = $.extend({},settings);

    var methods = {
        createDropDownCode: function(arr){

            // loop through li's of primary menu
            that.find("li").each(function(idx){

                $(this).append( menusort(arr.menu[idx].sub) );

                function menusort(data){
                    if(data !== null)   
                        var html = "<div><ul>";

                    for(item in data){
                        html += "<li>";
                        if(typeof(data[item].sub) === 'object'){
                            html += "<a href='" + data[item].link + "'>" + data[item].name + "</a>";
                            if($.isArray(data[item].sub))
                                html += menusort(data[item].sub);
                        }
                        html += "</li>"
                    }
                    if(data !== null)
                        html += "</ul></div>";
                    return html;
                }
            })
        },init: function(){
            var html = methods.createDropDownCode(settings.jsonData);

        }
    }

    methods.init();

}

解决方法

您可以尝试我刚刚编写的这个递归函数
function buildList(data,isSub){
    var html = (isSub)?'<div>':''; // Wrap with div if true
    html += '<ul>';
    for(item in data){
        html += '<li>';
        if(typeof(data[item].sub) === 'object'){ // An array will return 'object'
            if(isSub){
                html += '<a href="' + data[item].link + '">' + data[item].name + '</a>';
            } else {
                html += data[item].id; // Submenu found,but top level list item.
            }
            html += buildList(data[item].sub,true); // Submenu found. Calling recursively same method (and wrapping it in a div)
        } else {
            html += data[item].id // No submenu
        }
        html += '</li>';
    }
    html += '</ul>';
    html += (isSub)?'</div>':'';
    return html;
}

它返回菜单的html,所以使用它:var html = buildList(JSON.menu,false);

我相信它更快,因为它是纯JavaScript,并且它不会为每次迭代创建文本节点或DOM元素.只需在完成后调用.innerHTML或$(‘…’).html(),而不是立即为每个菜单添加HTML.

JSFiddled:http://jsfiddle.net/remibreton/csQL8/

相关文章

事件冒泡和事件捕获 起因:今天在封装一个bind函数的时候,发现el.addEventListener函数支持第三个参数...
js小数运算会出现精度问题 js number类型 JS 数字类型只有number类型,number类型相当于其他强类型语言...
什么是跨域 跨域 : 广义的跨域包含一下内容 : 1.资源跳转(链接跳转,重定向跳转,表单提交) 2.资源...
@ &quot;TOC&quot; 常见对base64的认知(不完全正确) 首先对base64常见的认知,也是须知的必须有...
搞懂:MVVM模式和Vue中的MVVM模式 MVVM MVVM : 的缩写,说都能直接说出来 :模型, :视图, :视图模...
首先我们需要一个html代码的框架如下: 我们的目的是实现ul中的内容进行横向的一点一点滚动。ul中的内容...