我如何从 JSON 数据递归创建 UL/LI 的 - 多层深度 [英] How can I recursively create a UL/LI's from JSON data - multiple layers deep

查看:19
本文介绍了我如何从 JSON 数据递归创建 UL/LI 的 - 多层深度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用以下 JSON 数据在递归内部函数中创建以下类似的结构,但运气不佳,确实需要一些帮助,所以如果有人可以提供帮助,请执行.提前致谢.

    <li></li><li><a href=""></a><div><ul><li><a href=""></a><div>....等等

我使用的JSON数据如下:

 var JSON = {菜单: [{id:'0',子:[{name: 'lorem ipsum 0-0',link: '0-0', sub: null},{name: 'lorem ipsum 0-1',link: '0-1', sub: null},{名称:'lorem ipsum 0-2',链接:'0-2',子:空}]},{id: '1',sub: null},{id:'2',子:[{name: 'lorem ipsum 2-0',link: '2-0', sub: null},{name: 'lorem ipsum 2-1',link: '2-1', sub: null},{名称:'lorem ipsum 2-2',链接:'2-2',子:[{name: 'lorem ipsum 2-2-0',link: '2-2-0', sub: null},{name: 'lorem ipsum 2-2-1',link: '2-2-1', sub: null},{name: 'lorem ipsum 2-2-2',link: '2-2-2', sub: null},{name: 'lorem ipsum 2-2-3',link: '2-2-3', sub: null},{name: 'lorem ipsum 2-2-4',link: '2-2-4', sub: null},{name: 'lorem ipsum 2-2-5',link: '2-2-5', sub: null},{名称:'lorem ipsum 2-2-6',链接:'2-2-6',子:空}]},{name: 'lorem ipsum 2-3',link: '2-3', sub: null},{name: 'lorem ipsum 2-4',link: '2-4', sub: null},{名称:'lorem ipsum 2-5',链接:'2-5',子:空}]},{id:'3',子:空}]}

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

$(function(){$.fn.dropdown = 功能(设置){var that = this;var settings = $.extend({}, $.fn.dropdown.defaults, settings);变量方法 = {isArray:函数(o){return Object.prototype.toString.call(o) === '[对象数组]';},createDropdownCode: 函数(arr){var 菜单 = arr.menu;var html = null;var menusort = 功能(菜单){html =那个;that.find("li").each(function(idx){var menuList = menu[idx].sub;var baseContainer = $(this);无功计数 = -1;var subsort = (function(){计数 += 1;返回函数(子菜单,pb){var 子块;subblock = $("

").append('
    ');如果(方法.isArray(子菜单)){for(var i=0;i");subblock.find('ul').append(l);if(pb !== undefined && i == submenu.length-1){pb.append(子块)}if(methods.isArray(submenu[i].sub)){subsort(submenu[i].sub, subblock.find('ul li').eq(i));}}}}})()子排序(菜单列表)})}菜单排序(菜单);返回空;//html !== null ?html.html() : 空;},初始化:函数(){//过滤json//创建 div=>ul=>liif(settings.jsonData === undefined || settings.jsonData === null){console.warn('没有 JSON 数据通过')返回;}别的{if(!methods.isArray(settings.jsonData.menu)){console.warn('没有 JSON 数据通过')返回;//错误,没有数据!}}//var html = methods.createBlock(settings.jsonData.menu[0].sub);var html = methods.createDropdownCode(settings.jsonData);//控制台.log(html)}}方法.init();返回那个;}$.fn.dropdown.defaults = {json数据:空}})$('#menu').dropdown({jsonData: JSON});

使用了集成代码,感谢给出足够接近答案的个人 - 尽管会研究其他人.

$.fn.dropdown = 函数(设置){var that = this;var settings = $.extend({}, $.fn.dropdown.defaults, settings);变量方法 = {createDropDownCode:函数(arr){//遍历主菜单的 lithat.find("li").each(function(idx){$(this).append( menusort(arr.menu[idx].sub) );功能菜单排序(数据){如果(数据!== 空)var html = "

你可以试试我刚刚编写的这个递归函数:

function buildList(data, isSub){var html = (isSub)?'

':'';//如果为真,则用 div 包裹html += '
    ';for(数据中的项目){html += '
  • ';if(typeof(data[item].sub) === 'object'){//数组将返回 'object'如果(isSub){html += '<a href="' + data[item].link + '">'+ data[item].name + '</a>';} 别的 {html += 数据[项目].id;//找到子菜单,但顶级列表项.}html += buildList(data[item].sub, true);//找到子菜单.递归调用相同的方法(并将其包装在 div 中)} 别的 {html += data[item].id//无子菜单}html += '</li>';}html += '</ul>';html += (isSub)?'</div>':'';返回html;}

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

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

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

I am trying to use use the following JSON data to create the following similar structure in a recursive inner function with not much luck, really need some help and so if anyone can assist please do. Thank you in advance.

<ul>
    <li></li>
    <li>
        <a href=""></a>
        <div>
            <ul>
                <li>
                    <a href=""></a>
                    <div>
                         ....etc
                    </div>
                </li>
            </ul>
        </div>
    </li>
</ul>

the JSON data I am using is as follows:

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

and the code I have created (incomplete, this is the brain teaser I need help on) is:

$(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
});

integrated code used, thanks to the individual that gave a close enough answer - Although will study the others.

$.fn.dropdown = function(settings){

    var that = this;
    var settings = $.extend({}, $.fn.dropdown.defaults, 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();

}

解决方案

You can try this recursive function I've just coded:

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;
}

It returns the html for the menu, so use it like that: var html = buildList(JSON.menu, false);

I believe it is faster because it's in pure JavaScript, and it doesn't create text nodes or DOM elements for every iteration. Just call .innerHTML or $('...').html() at the end when you're done instead of adding HTML immediately for every menu.

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

这篇关于我如何从 JSON 数据递归创建 UL/LI 的 - 多层深度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆