Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何递归地创建UL/LI';来自JSON数据的s-多层_Javascript_Json_Recursion_Menu - Fatal编程技术网

Javascript 如何递归地创建UL/LI';来自JSON数据的s-多层

Javascript 如何递归地创建UL/LI';来自JSON数据的s-多层,javascript,json,recursion,menu,Javascript,Json,Recursion,Menu,我正在尝试使用以下JSON数据在递归内部函数中创建以下类似结构,运气不好,确实需要一些帮助,因此如果有人可以提供帮助,请提供帮助。先谢谢你 <ul> <li></li> <li> <a href=""></a> <div> <ul> <li> &l

我正在尝试使用以下JSON数据在递归内部函数中创建以下类似结构,运气不好,确实需要一些帮助,因此如果有人可以提供帮助,请提供帮助。先谢谢你

<ul>
    <li></li>
    <li>
        <a href=""></a>
        <div>
            <ul>
                <li>
                    <a href=""></a>
                    <div>
                         ....etc
                    </div>
                </li>
            </ul>
        </div>
    </li>
</ul>
我创建的代码(不完整,这是我需要帮助的脑筋急转弯)是:

$(函数(){
$.fn.dropdown=功能(设置){
var=这个;
变量设置=$.extend({},$.fn.dropdown.defaults,settings);
var方法={
isArray:函数(o){
返回Object.prototype.toString.call(o)='[objectarray]';
},
createDropdownCode:函数(arr){
var菜单=arr.menu;
var html=null;
var menusort=功能(菜单){
html=那个;
查找(“li”)。每个(函数(idx){
var menuList=菜单[idx].sub;
var baseContainer=$(这个);
var计数=-1;
var subsort=(函数(){
计数+=1;
返回功能(子菜单,pb){
var子块;
子块=$(“”)。追加(“
    ”); if(methods.isArray(子菜单)){ 对于(var i=0;iul=>li if(settings.jsonData==undefined | | settings.jsonData==null){ console.warn('没有传递JSON数据') 返回; }否则{ if(!methods.isArray(settings.jsonData.menu)){ console.warn('没有传递JSON数据') return;//错误,没有数据! } } //var html=methods.createBlock(settings.jsonData.menu[0].sub); var html=methods.createDropdownCode(settings.jsonData); //console.log(html) } } 方法init(); 归还; } $.fn.dropdown.defaults={ jsonData:null } }) $(“#菜单”)。下拉列表({ jsonData:JSON });
使用了集成代码,这要感谢给出了足够接近答案的个人——尽管他会研究其他人

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

}
$.fn.dropdown=功能(设置){
var=这个;
变量设置=$.extend({},$.fn.dropdown.defaults,settings);
var方法={
createDropDownCode:函数(arr){
//循环浏览主菜单中的li
查找(“li”)。每个(函数(idx){
$(this.append(menusort(arr.menu[idx].sub));
函数菜单排序(数据){
如果(数据!==null)
var html=“
    ”; 用于(数据中的项目){ html+=“
  • ”; if(typeof(数据[项].sub)==“对象”){ html+=“”; if($.isArray(数据[项目].sub)) html+=menusort(数据[项].sub); } html+=“
  • ” } 如果(数据!==null) html+=“
”; 返回html; } }) }, init:function(){ var html=methods.createDropDownCode(settings.jsonData); } } 方法init(); }
在每个元素上调用两个函数
makeUL
makeLI
makeUL
调用
makeLI
,如果存在
元素,则调用
makeUL

function makeUL(lst) {
    ...
    $(lst).each(function() { html.push(makeLI(this)) });
    ...
    return html.join("\n");
}

function makeLI(elem) {
    ...
    if (elem.sub)
        html.push('<div>' + makeUL(elem.sub) + '</div>');
    ...
    return html.join("\n");
}
函数makeUL(lst){
...
$(lst).each(function(){html.push(makeLI(this))});
...
返回html.join(“\n”);
}
函数makeLI(elem){
...
if(要素子项)
html.push(“”+makeUL(elem.sub)+“”);
...
返回html.join(“\n”);
}


需要根据您的需要进行调整,但您已经想到了。

您可以尝试我刚刚编写的递归函数:

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;
}
函数构建列表(数据,ISUB){
var html=(isSub)?“”;//如果为true,则用div换行
html+='
    '; 用于(数据中的项目){ html+=“
  • ”; 如果(typeof(data[item].sub)==“object”){//数组将返回“object” 如有(b){ html+=''; }否则{ html+=data[item].id;//找到了子菜单,但找到了顶级列表项。 } html+=buildList(data[item].sub,true);//找到子菜单。递归调用相同的方法(并将其包装在div中) }否则{ html+=数据[项].id//无子菜单 } html+='
  • '; } html+='
'; html+=(ISUB)?“”:“”; 返回html; }
它返回菜单的html,所以像这样使用:
var html=buildList(JSON.menu,false);

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


jsfiddle:

此解决方案使用单个递归函数。我通过使用
数组
映射()
函数简化了逻辑

$(函数(){
$(“body”).html(makeUnorderedList(getData().menu));
});
函数makeUnorderedList(数据,li){
返回$('
    ).append(data.map)(函数(el){ var li=li | |$(“
  • ”); 如果(el.id | | el.link)li.append($(''){ 文本:el.id | | el.link, href:“#”+(el.id | | el.link), 姓名:el.name })); if(el.sub)li.append(makeUnorderedList(el.sub,li)); 返回李; })); } 函数getData(){ 返回{
    function makeUL(lst) {
        ...
        $(lst).each(function() { html.push(makeLI(this)) });
        ...
        return html.join("\n");
    }
    
    function makeLI(elem) {
        ...
        if (elem.sub)
            html.push('<div>' + makeUL(elem.sub) + '</div>');
        ...
        return html.join("\n");
    }
    
    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;
    }
    
    var jsonstring = [{
      "id": '1',
      "children": [{
        "id": '2'
      }, {
        "id": '3',
        "children": [{
          "id": '4'
        }]
      }]
    }, {
      "id": '5'
    }];
    
     var htmlStr= recurse( jsonstring );
    $('#test').append(htmlStr);
    
    
    function recurse( data ) {
      var htmlRetStr = "<ul>"; 
      for (var key in data) { 
            if (typeof(data[key])== 'object' && data[key] != null) {
            var x=key*1;        
            if(isNaN(x)){
                htmlRetStr += "<li>" + key + ":<ul>";
                }
                htmlRetStr += recurse( data[key] );
                htmlRetStr += '</ul></li>';
            } else {
                htmlRetStr += ("<li>" + key + ': &quot;' + data[key] + '&quot;</li  >' );
            }
      };
      htmlRetStr += '</ul >';    
      return( htmlRetStr );
    }
    
    <div id="test"></div>
    
    li ul ul li {
        padding-left: 10px;
    }
    
    li ul ul ul {
        padding: 0px;
    }
    
    function drawRecElements(arr, html, elements) {
        if (typeof (html) === 'undefined') {
            var html = '';
        }
        if (typeof (elements) === 'undefined') {
            var elements = {child: '<li>', childClose: '</li>', parent: '<ul>', parentClose: '</ul>'};
        }
        if (typeof (arr) === 'string') {
            return elements.child + arr + elements.childClose;
        } else if (typeof (arr) === 'object') {
            for (i in arr) {
                if (typeof (arr[i]) === 'string') {
                    html += elements.parent + elements.child + i + elements.childClose + elements.child + arr[i] + elements.childClose + elements.parentClose;
                } else if(typeof (i) === 'string' && (isNaN(i))){
                    html += elements.parent + elements.child + i + elements.childClose + elements.child + drawRecElements(arr[i],'',elements) + elements.childClose + elements.parentClose;
                } else if (typeof (arr[i]) === 'object') {
                   html = drawRecElements(arr[i], html,elements);
                }
            }
        }
        return html;
    }
    
    var config = {
        "Menu-1-Level-1": {
            "label": "Menu-1-Level-1",
            "type": "treeView",
            "class": "Menu-1-Level-1",
            "children": [
                {
                    label: "Menu-1-Level-2",
                    type: "treeView",
                    "class": "Menu-1-Level-2",
                    children: [
                        {
                            label: "Menu-1-Level-3",
                            class: "Menu-1-Level-3"
                        }
                    ]
                },
                {
                    label : "Menu-2-Level-2",
                    class: "Menu-2-Level-2"
                }
            ]
        },
        "Menu-2-Level-1": {
            "label": "Menu-2-Level-1",
            "type": "treeView",
            "class": "Menu-2-Level-1",
            "children": [
                {
                    label: "Menu-1-Level-2",
                    class: "Menu-1-Level-2",
                    type: "treeView",
                    children: [
                        {
                            label: "Menu-1-Level-3",
                            class: "Menu-1-Level-3"
                        }
                    ]
                },
                {
                    label : "Menu-2-Level-2",
                    class : "Menu-2-Level-2"
                }
            ]
        }
    };
    
    <!DOCTYPE html>
    <html>
    
    <head>
        <title>Tree Menu</title>
        <script src="http://code.jquery.com/jquery-1.11.2.min.js" type="text/javascript"></script>
        <script src="tree.js" type="text/javascript"></script>
        <link href="tree.css" rel="stylesheet">
    </head>
    
    <body>
        <div class="treeContainer">
            <div class="tree"></div>
        </div>
        <script src="testPage.js" type="text/javascript"></script>
    </body>
    
    </html>
    
    var tree;
    
    tree = function (treeNodeParent, dataObj) {
        this.dataObj = dataObj;
        this.treeNodeParent = treeNodeParent;
        this.treeNode = $(document.createElement("ul")).addClass("treeNode");
    };
    
    tree.prototype.expandCollapse = function (e) {
        var target = $(e.currentTarget), parentLabel = target.parent();
    
        if (parentLabel.hasClass("collapsed")) {
            parentLabel.removeClass("collapsed").addClass("expanded");
        } else {
            parentLabel.addClass("collapsed").removeClass("expanded");
        }
    };
    
    tree.prototype.attachEvents = function () {
        var me = this;
        me.treeNodeParent.delegate(".collapsed label, .expanded label", "click", me.expandCollapse);
    };
    
    tree.prototype.attachMarkUp = function () {
        var me = this;
        me.treeNodeParent.append(me.treeNode);
    };
    
    tree.prototype.getEachNodeMarkup = function (nodeObj, rootNode, selector) {
        var selectedNode, i, me = this;
    
        if (nodeObj.children) {
    
            if (!selector) {
                selectedNode = rootNode;
            } else {
                selectedNode = rootNode.find(selector);
            }
    
            nodeObj.class = nodeObj.class ? nodeObj.class : "";
            selectedNode.append($.parseHTML("<li name=" + nodeObj.label + " class='collapsed " + nodeObj.class + "'>" + "<label>" + nodeObj.label + "</label>" + "<ul></ul></li>"));
            selector = selector + " li[name=" + nodeObj.label + "] > ul";
    
            for (i = 0; i < nodeObj.children.length; i = i + 1) {
                me.getEachNodeMarkup(nodeObj.children[i], rootNode, selector);
            }
    
        } else {
            nodeObj.class = nodeObj.class ? nodeObj.class : "";
            rootNode.find(selector).append($.parseHTML("<li name=" + nodeObj.label + " class='" + nodeObj.class + "'>" + "<label>" + nodeObj.label + "</label>" + "</li>"));
        }
    };
    
    tree.prototype.getTree = function () {
        var component, me = this;
    
        for (component in me.dataObj) {
            if (me.dataObj.hasOwnProperty(component)) {
                me.getEachNodeMarkup(me.dataObj[component], me.treeNode, "");
            }
        }
        me.attachMarkUp();
        me.attachEvents();
        return me.treeNode;
    };
    
    .treeNode .collapsed > ul, .collapsed > li {
        display: none;
    }
    
    .treeNode .expanded > ul, .expanded > li {
        display: block;
    }
    
    // the variable "config" is nothing but the config JSON defined initially. 
    treeNode = new tree($('.treeContainer .tree'), config); 
    treeNodeObj = treeNode.getTree();
    
    var foo=(arg)=>
    `<ul>
    ${arg.map(elem=>
        elem.sub?
            `<li>${foo(elem.sub)}</li>`
            :`<li>${elem.name}</li>`
        ).join('')}
    </ul>`
    
       var bar = [
      {
        name: 'Home'
      }, {
        name: 'About'
      }, {
        name: 'Portfolio'
      }, {
        name: 'Blog'
      }, {
        name: 'Contacts'
      }, {
        name: 'Features',
        sub: [
          {
            name: 'Multipage'
          }, {
            name: 'Options',
            sub: [
              {
                name: 'General'
              }, {
                name: 'Sidebars'
              }, {
                name: 'Fonts'
              }, {
                name: 'Socials'
              }
            ]
          }, {
            name: 'Page'
          }, {
            name: 'FAQ'
          }
        ]
      }
    ]
    var result=foo(bar)