Javascript 多级菜单
我一直在琢磨如何让这个动态菜单以一种比我现在更干净的方式工作,我现在收到一个菜单项列表作为一个平面XML结构 我在下面创建了一个对象,说明了数据在对象内部的外观,它对每个菜单项都有父子关系(为了便于阅读,我缩进了) 我想知道如何动态地创建菜单对象(使用递归函数,我认为这是最理想的),而不必为菜单的每个级别使用不同的函数,这是我的代码目前的样子,它仅限于菜单的3个级别 我想要的是一个很好的功能,它将接受任何数量的菜单级别Javascript 多级菜单,javascript,twitter-bootstrap,ecmascript-6,Javascript,Twitter Bootstrap,Ecmascript 6,我一直在琢磨如何让这个动态菜单以一种比我现在更干净的方式工作,我现在收到一个菜单项列表作为一个平面XML结构 我在下面创建了一个对象,说明了数据在对象内部的外观,它对每个菜单项都有父子关系(为了便于阅读,我缩进了) 我想知道如何动态地创建菜单对象(使用递归函数,我认为这是最理想的),而不必为菜单的每个级别使用不同的函数,这是我的代码目前的样子,它仅限于菜单的3个级别 我想要的是一个很好的功能,它将接受任何数量的菜单级别 function createRoot(){ // Initial
function createRoot(){
// Initially map all root elements
Menu.map((item, index) => {
if (item.ParentMenuID === "?"){
// If the the next menu item is a child of this root
if (Menu[index+1].ParentMenuID === item.MenuID){
// Generate boilerplate dropdown code + then retrieve it's children
htmlStr += `<li class="dropdown-submenu"><a class="test" data-menuID="`+item.MenuID+`" data-menuitem="`+item.href+`" href="#">`+item.DisplayName+`<span class="caret"></a>`
htmlStr += `<ul class="dropdown-menu">`
GetLevel1(item);
htmlStr += `</ul>`
htmlStr += `</li>`
// Otherwise it's just a normal menu item
} else {
htmlStr += `<li><a class="test" data-menuID="`+item.MenuID+`" data-menuitem="`+item.href+`" href="#">`+item.DisplayName+`</a></li>`
}
}
});
$('#user-menu-list').html(htmlStr);
// Setup event on list items
$('.dropdown-submenu a.test').on("click", function(e){
$(this).next('ul').toggle();
e.stopPropagation();
e.preventDefault();
});
}
function GetLevel1(item){
Menu.map((subItem, index) => {
if (index < Menu.length-1){
console.log(index);
// If the current item is a child of the root
if (subItem.ParentMenuID === item.MenuID){
// If the the next item is a child of this root
if (Menu[index+1].ParentMenuID === subItem.MenuID){
htmlStr += `<li class="dropdown-submenu"><a class="test" data-menuID="`+subItem.MenuID+`" data-menuitem="`+subItem.href+`" href="#">`+subItem.DisplayName+`<span class="caret"></a>`
htmlStr += `<ul class="dropdown-menu">`
GetLevel2(subItem);
htmlStr += `</ul>`
htmlStr += `</li>`
} else {
htmlStr += `<li><a class="test" data-menuID="`+subItem.MenuID+`" data-menuitem="`+subItem.href+`" href="#">`+subItem.DisplayName+`</a></li>`
}
}
}
});
}
function GetLevel2(item){
Menu.map((subItem, index) => {
console.log("INDEX: "+index);
// If the current item is a child of the root
if (subItem.ParentMenuID === item.MenuID){
htmlStr += `<li><a class="test" data-menuID="`+subItem.MenuID+`" data-menuitem="`+subItem.href+`" href="#">`+subItem.DisplayName+`</a></li>`
}
});
}
createRoot();
函数createRoot(){
//最初映射所有根元素
Menu.map((项目,索引)=>{
如果(item.ParentMenuID==“?”){
//如果下一个菜单项是此根的子项
if(菜单[index+1].ParentMenuID==item.MenuID){
//生成样板文件下拉代码+然后检索其子项
htmlStr+=``
htmlStr+=``
GetLevel1(项目);
htmlStr+=`
`
htmlStr+=` `
//否则它只是一个普通的菜单项
}否则{
htmlStr+=``
}
}
});
$(“#用户菜单列表”).html(htmlStr);
//列表项上的设置事件
$('.dropdown子菜单a.test')。打开(“单击”,函数(e){
$(this.next('ul').toggle();
e、 停止传播();
e、 预防默认值();
});
}
函数GetLevel1(项){
Menu.map((子项,索引)=>{
如果(索引<菜单长度-1){
控制台日志(索引);
//如果当前项是根的子项
if(subItem.ParentMenuID==item.MenuID){
//如果下一项是此根的子项
if(菜单[index+1].ParentMenuID==子项.MenuID){
htmlStr+=``
htmlStr+=``
第二级(分项);
htmlStr+=`
`
htmlStr+=` `
}否则{
htmlStr+=``
}
}
}
});
}
功能GetLevel2(项目){
Menu.map((子项,索引)=>{
控制台日志(“索引:”+索引);
//如果当前项是根的子项
if(subItem.ParentMenuID==item.MenuID){
htmlStr+=``
}
});
}
createRoot();
这是一个完整的pastebin链接,我的菜单目前正在运行:
任何帮助都将不胜感激 我的递归能力有些生疏,这是可以改进的, 我会这样做, 首先浏览所有菜单,将子菜单添加到其父菜单 第一阶段完成后,我在一个对象中拥有菜单和子菜单,您可以再次执行递归并构建菜单 大概是这样的:
var菜单=[{
显示名称:“菜单1”,
href:“Menu1.aspx”,
MenuID:“1”,
ParentMenuID:“?”,
职位:“1”,
用户类型代码:“99”
}, {
显示名称:“菜单-1-1”,
href:“Menu1.aspx”,
MenuID:“2”,
ParentMenuID:“1”,
职位:“1”,
用户类型代码:“99”
}, {
显示名称:“菜单-1-2”,
href:“Menu1.aspx”,
MenuID:“3”,
ParentMenuID:“1”,
立场:“2”,
用户类型代码:“99”
}, {
显示名称:“菜单2”,
href:“Menu2.aspx”,
MenuID:“4”,
ParentMenuID:“?”,
立场:“2”,
用户类型代码:“99”
}, {
显示名称:“菜单2-1”,
href:“Menu1.aspx”,
MenuID:“5”,
ParentMenuID:“4”,
职位:“1”,
用户类型代码:“99”
}, {
显示名称:“菜单2-2”,
href:“Menu1.aspx”,
菜单:“6”,
ParentMenuID:“4”,
立场:“2”,
用户类型代码:“99”
}, {
显示名称:“菜单2-2-1”,
href:“Menu1.aspx”,
菜单:“7”,
ParentMenuID:“6”,
职位:“1”,
用户类型代码:“99”
}];
var main=[];
函数getSiblins(currentNode,currentId){
如果(!currentId){
currentNode.children=currentNode.children | |新数组();
返回getSiblins(currentNode,currentNode.MenuID)
}否则{
对于(var j=0;j”+currentMenu.DisplayName+”“
对于(变量i=0;i”+prepareMenu(currentMenu.children[i])+“”;
}
返回HTML;
}
var menuHtml=“”;
对于(var j=0;j
.children li{
颜色:蓝色;
}
.孩子们{
颜色:绿色;
}
递归函数在这里似乎很好。这正是我真正想要的,但我不知道如何在这种情况下实现它
function createRoot(){
// Initially map all root elements
Menu.map((item, index) => {
if (item.ParentMenuID === "?"){
// If the the next menu item is a child of this root
if (Menu[index+1].ParentMenuID === item.MenuID){
// Generate boilerplate dropdown code + then retrieve it's children
htmlStr += `<li class="dropdown-submenu"><a class="test" data-menuID="`+item.MenuID+`" data-menuitem="`+item.href+`" href="#">`+item.DisplayName+`<span class="caret"></a>`
htmlStr += `<ul class="dropdown-menu">`
GetLevel1(item);
htmlStr += `</ul>`
htmlStr += `</li>`
// Otherwise it's just a normal menu item
} else {
htmlStr += `<li><a class="test" data-menuID="`+item.MenuID+`" data-menuitem="`+item.href+`" href="#">`+item.DisplayName+`</a></li>`
}
}
});
$('#user-menu-list').html(htmlStr);
// Setup event on list items
$('.dropdown-submenu a.test').on("click", function(e){
$(this).next('ul').toggle();
e.stopPropagation();
e.preventDefault();
});
}
function GetLevel1(item){
Menu.map((subItem, index) => {
if (index < Menu.length-1){
console.log(index);
// If the current item is a child of the root
if (subItem.ParentMenuID === item.MenuID){
// If the the next item is a child of this root
if (Menu[index+1].ParentMenuID === subItem.MenuID){
htmlStr += `<li class="dropdown-submenu"><a class="test" data-menuID="`+subItem.MenuID+`" data-menuitem="`+subItem.href+`" href="#">`+subItem.DisplayName+`<span class="caret"></a>`
htmlStr += `<ul class="dropdown-menu">`
GetLevel2(subItem);
htmlStr += `</ul>`
htmlStr += `</li>`
} else {
htmlStr += `<li><a class="test" data-menuID="`+subItem.MenuID+`" data-menuitem="`+subItem.href+`" href="#">`+subItem.DisplayName+`</a></li>`
}
}
}
});
}
function GetLevel2(item){
Menu.map((subItem, index) => {
console.log("INDEX: "+index);
// If the current item is a child of the root
if (subItem.ParentMenuID === item.MenuID){
htmlStr += `<li><a class="test" data-menuID="`+subItem.MenuID+`" data-menuitem="`+subItem.href+`" href="#">`+subItem.DisplayName+`</a></li>`
}
});
}
createRoot();