多级菜单
Multi-Level Menu
我一直在想如何让这个动态菜单以比目前更干净的方式工作,我目前收到一个菜单项列表作为平面 XML 结构。
我在下面创建了一个对象,说明了数据在对象内部的外观,它对每个菜单项都有父子关系(为了便于阅读,我缩进了)
let Menu = [
{
DisplayName : "Menu1",
href : "Menu1.aspx",
MenuID : "1",
ParentMenuID : "?",
Position : "1",
UserTypeCode : "99"
},
{
DisplayName : "Menu-1-1",
href : "Menu1.aspx",
MenuID : "2",
ParentMenuID : "1",
Position : "1",
UserTypeCode : "99"
},
{
DisplayName : "Menu-1-2",
href : "Menu1.aspx",
MenuID : "3",
ParentMenuID : "1",
Position : "2",
UserTypeCode : "99"
},
{
DisplayName : "Menu2",
href : "Menu2.aspx",
MenuID : "4",
ParentMenuID : "?",
Position : "2",
UserTypeCode : "99"
},
{
DisplayName : "Menu2-1",
href : "Menu1.aspx",
MenuID : "5",
ParentMenuID : "4",
Position : "1",
UserTypeCode : "99"
},
{
DisplayName : "Menu2-2",
href : "Menu1.aspx",
MenuID : "6",
ParentMenuID : "4",
Position : "2",
UserTypeCode : "99"
},
{
DisplayName : "Menu2-2-1",
href : "Menu1.aspx",
MenuID : "7",
ParentMenuID : "6",
Position : "1",
UserTypeCode : "99"
}
];
我想知道我如何动态创建菜单对象(使用我认为是理想的递归函数),而无需我目前有点混乱的解决方案,即需要为菜单的每个级别使用不同的函数,这是我的代码目前的样子,它仅限于菜单的 3 个级别
我想要的是一个不错的功能,它可以接受任意数量的菜单级别
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();
这是一个完整的粘贴链接,我的菜单目前正在运行:http://pastebin.com/ektBQ7kd
任何帮助将不胜感激!
我的递归能力有点生疏,可以改进,我会做这样的事情,首先浏览所有菜单,将孩子菜单添加到他们的父母。
第一阶段完成后,我在一个对象中有菜单和子菜单,您可以再次执行递归并构建菜单。
像这样:
var Menu = [{
DisplayName: "Menu1",
href: "Menu1.aspx",
MenuID: "1",
ParentMenuID: "?",
Position: "1",
UserTypeCode: "99"
}, {
DisplayName: "Menu-1-1",
href: "Menu1.aspx",
MenuID: "2",
ParentMenuID: "1",
Position: "1",
UserTypeCode: "99"
}, {
DisplayName: "Menu-1-2",
href: "Menu1.aspx",
MenuID: "3",
ParentMenuID: "1",
Position: "2",
UserTypeCode: "99"
}, {
DisplayName: "Menu2",
href: "Menu2.aspx",
MenuID: "4",
ParentMenuID: "?",
Position: "2",
UserTypeCode: "99"
}, {
DisplayName: "Menu2-1",
href: "Menu1.aspx",
MenuID: "5",
ParentMenuID: "4",
Position: "1",
UserTypeCode: "99"
}, {
DisplayName: "Menu2-2",
href: "Menu1.aspx",
MenuID: "6",
ParentMenuID: "4",
Position: "2",
UserTypeCode: "99"
}, {
DisplayName: "Menu2-2-1",
href: "Menu1.aspx",
MenuID: "7",
ParentMenuID: "6",
Position: "1",
UserTypeCode: "99"
}];
var main = [];
function getSiblins(currentNode, currentId) {
if (!currentId) {
currentNode.children = currentNode.children || new Array();
return getSiblins(currentNode, currentNode.MenuID)
} else {
for (var j = 0; j < Menu.length; j++) {
if (Menu[j].ParentMenuID == currentId) {
currentNode.children.push(Menu[j]);
}
}
}
if (currentNode.ParentMenuID == "?") {
//root menu
main.push(currentNode);
}
}
for (var i = 0; i < Menu.length; i++)
getSiblins(Menu[i]);
function prepareMenu(currentMenu) {
var appendHtml = "<li>" + currentMenu.DisplayName + "</li>"
for (var i = 0; i < currentMenu.children.length; i++) {
appendHtml = appendHtml + "<ul class='children'>" + prepareMenu(currentMenu.children[i]) + "</ul>";
}
return appendHtml;
}
var menuHtml = "";
for (var j = 0; j < main.length; j++) {
menuHtml += prepareMenu(main[j]);
}
document.getElementById("finalMenu").innerHTML = menuHtml;
.children li{
color: blue;
}
.children .children li {
color: green;
}
<ul id="finalMenu">
</ul>
相关文章:
- jQuery-适用于移动设备的多级菜单
- 可替代多级上下文菜单
- slideDown菜单-添加更多级别的问题
- 悬停样式应该在动态加载多级菜单时保持单击状态
- 多级手风琴式导航菜单
- 如何在不插入整个代码的情况下嵌入现有的多级下拉菜单
- 如果菜单处于活动状态或非活动状态,则切换图标的类.多级按钮菜单
- 使用 jquery 的多级下拉菜单
- 记住菜单状态垂直多级导航
- 多级响应菜单..移动和非移动之间的转换
- 多级菜单的角度指令
- 常见问题解答的多级菜单
- 多级可折叠引导侧导航菜单出现问题
- 从一页到另一页的多级推送菜单状态
- Javascript多级下拉菜单
- 如何添加多级菜单
- 如何停止 e.prevent默认在创建响应式多级菜单时禁用子链接
- 使“多级推送”菜单在IE中工作
- 如何从字符串创建多级列表菜单
- 尝试从实现多级推送菜单http://multi-level-push-menu.make.rs在网站上