如何在JavaScript中递归制作菜单和子菜单?

时间:2019-04-19 10:58:20

标签: javascript json recursion

我想提供递归和动态功能来呈现导航菜单和子菜单

我有一个对象的JSON数组,其中每个对象都是菜单项,菜单项可以有子菜单,还有子菜单也有子子菜单。...我想你理解我的逻辑。

当前,每个对象都有标题和子菜单对象。

JSON对象

[
{
    title: "menu 1"
    submenus: [
        {
            title: "sub menu1"
        },
        {
            title: "sub menu2"
            submenus: [
                {
                    title: "subsub menu1"
                    submenus: [
                        {
                            title: "susubsub menu1"
                        }
                    ]
                },
                {
                    title: 'subsub menu2"
                }
            ]
        }
    ]
},
{
    title: "menu 2"
}]

有什么想法吗?

4 个答案:

答案 0 :(得分:0)

示例:

  var a = {
  "menu1": {
     title: "menu1"
   },
   "menu2": {
     title: "menu2",
     submenu: {
       "menu3" : {
          title : "menu3"
        },
       "menu4": {
         title: "menu4",
         submenu: {
          "menu5": {
           title: "menu5"
         }
       }
     }
   }
  }
 }



 function printMenu(menu){
     if(!menu) return "";

     var str = "";
     for(var i in menu)
     {
         if(menu[i].submenu)
            str+= "<li>"+menu[i].title+"<ul>"+printMenu(menu[i].submenu)+"</ul></li>";
         else
            str+= "<li>"+menu[i].title+"</li>";
     }
     return str;
 };

printMenu(a); // "<li>menu1</li><li>menu2<ul><li>menu3</li><li>menu4<ul><li>menu5</li></ul></li></ul></li>"

答案 1 :(得分:0)

下面是一个示例,说明如何使用递归进入JSON中的每个菜单和子菜单:

var myJson ='[{"title": "menu 1", "submenus": ['+
        '{"title": "sub menu1"},'+
        ' {"title": "sub menu2", "submenus": ['+
              ' {"title": "subsub menu1", "submenus": [{"title": "susubsub menu1"}]},'+
                ' {"title": "subsub menu2"}'+
            ']}]},'+
'{"title": "menu 2"}]';
var obj = JSON.parse(myJson);

function recursive(object){
  if(object){
    for(var i = 0; i < object.length; i++){
      console.log(object[i].title);
        recursive(object[i].submenus);
    }
  }
}
recursive(obj);

答案 2 :(得分:0)

有几个JavaScript库可以生成带有各种视觉辅助工具的动态菜单。但是,如果您自己实现它,则将使用以下成分:

  • 应该在其中放置菜单的容器HTML元素。
  • JavaScript递归函数,用于为菜单创建DOM元素并将其放置在容器元素中
  • 单击处理程序,可通过样式切换子菜单的可见性
  • CSS为菜单提供一些视觉提示,并提供显示或隐藏子菜单的样式

例如:

function populateMenu(container, menu) {
    if (!menu || !menu.length) return;
    const ul = document.createElement("ul");
    for (const {title, submenus} of menu) {
        const li = document.createElement("li");
        li.textContent = title;
        li.className = "leaf";       
        if (submenus) {
            populateMenu(li, submenus, true);
            li.className = "collapsed";       
            li.addEventListener("click", (e) => { 
                if (e.target !== e.currentTarget) return;
                e.target.classList.toggle("expanded");
                e.target.classList.toggle("collapsed");
            });
        }
        ul.appendChild(li);
    }
    container.appendChild(ul);
}

// Example menu definititon:
const menu = [{ title: "menu 1", submenus: [{ title: "sub menu1" }, { title: "sub menu2", submenus: [{ title: "subsub menu1", submenus: [{ title: "susubsub menu1"}]}, { title: "subsub menu2" }]}]}, { title: "menu 2" }];
// Provide the DOM element where the menu should be inserted:
populateMenu(document.getElementById("menu"), menu);
li.collapsed > ul { display: none }
ul { cursor: pointer }
li.collapsed, li.expanded, li.leaf {
    position: relative;
    list-style-type: none;
    text-indent: -2em;
}
li.expanded:before { content: '−  ' }
li.collapsed:before { content: '+  ' }
li.leaf:before { content: '○  ' }
<div id="menu"></div>

答案 3 :(得分:0)

遍历第n级嵌套数组列表,并根据需要在递归函数中编写逻辑代码。

我实现了这段代码,用于为PrimeNG的上下文菜单生成菜单列表。

JSON数据-

    [
      {
        "TITLE": "parent1",
        "SUBMENU": [
          {
            "SUBMENU": [
              {
                "SUBMENU": [
                  {
                    "TITLE": "Child 1"
                  }
                ]
              },
              {
                "SUBMENU": [
                  {
                    "TITLE": "Child 3"
                  }
                ]
              },
              {
                "SUBMENU": [
                  {
                    "SUBMENU": [
                      {
                        "TITLE": "Child 4"
                      }
                    ]
                  },
                  {
                    "SUBMENU": [

                    ]
                  }
                ],

              },
              {
                "SUBMENU": [
                  {
                    "SUBMENU": [

                    ]
                  }
                ]
              }
            ],

          }
        ],

      },
      {
        "TITLE": "parent2",
        "SUBMENU": [
          {
            "TITLE": "Child 4"
          }
        ],

      }
    ]

JAVASCRIPT /打字稿代码-

traveRecusrivelist(object: any[]): any[] {
    if (object) {
      let newList: any[] = [];
      for (var i = 0; i < object.length; i++) {
        if (object[i].ITEMS && object[i].ITEMS.length > 0) {
            // TODO : code you logic here
           // create your own object and push in the newList array
          let returnedList = this.traveRecusrivelist(object[i].ITEMS);
          // Example : PrimeNG MenuItem creation
          // newList.push({ label: object[i].TITLE, items: returnedList, command: (event) => { } });
          newList.push(returnedList);
        }
        else {
            // TODO : code you logic here
           // example : PrimeNG menuItem 
           // newList.push({ label: object[i].TITLE, command: (event) => { } });
           // create your own object and push in the newList array
              newList.push(object[i]);
        }
      }
      return newList;
    }
  }

let list: any[] = [];
list = this.traveRecusrivelist(object);
console.log(list);