如何用jQuery Ajax实现侧边栏层级动态菜单结构?
解决jQuery构建层级侧边栏菜单的问题
你的代码之所以出现不符合预期的输出,核心问题是循环逻辑没有正确区分父菜单和子菜单的归属关系,而且每次操作都会选中所有已创建的父菜单元素,导致子菜单重复添加到所有父菜单里。咱们一步步来修正:
问题分析
- 每次循环到
ParentID == '0'的父菜单时,你用$(".mainLi")选中了所有已存在的父菜单li,给它们都添加了.goksel的ul,这会让之前的父菜单被重复添加ul。 list变量指向的是所有.goksel元素,后续append子菜单时,会把当前循环的菜单(不管是父还是子)都加到所有父菜单的ul里,完全打乱了层级结构。- 没有建立父菜单ID和对应子菜单的关联,只是按顺序循环数据,导致子菜单无法正确归属到对应的父菜单下。
正确实现方案
我们可以先把菜单数据按ParentID分组,先处理所有父菜单,再给每个父菜单匹配对应的子菜单,这样结构就清晰了:
success: function (data) { // 1. 先把菜单数据按ParentID分组,方便后续匹配父子菜单 const menuGroups = {}; data.d.forEach(menuItem => { // 如果当前ParentID还没有分组,初始化一个空数组 if (!menuGroups[menuItem.ParentID]) { menuGroups[menuItem.ParentID] = []; } menuGroups[menuItem.ParentID].push(menuItem); }); // 2. 获取所有父菜单(ParentID为'0'的项) const parentMenus = menuGroups['0'] || []; // 3. 遍历父菜单,构建层级结构 parentMenus.forEach(parentMenu => { // 创建父菜单的li元素 const parentLi = $(` <li class="mainLi"> <a class="has-arrow waves-effect waves-dark" href="#" aria-expanded="false"> <i class="fas fa-chart-line"></i> <span class="hide-menu lang" data-key="${parentMenu.MenuID}">${parentMenu.MenuName}</span> </a> </li> `); // 将父菜单添加到侧边栏容器 $("#sidebarnav").append(parentLi); // 4. 获取当前父菜单对应的子菜单 const childMenus = menuGroups[parentMenu.MenuID] || []; if (childMenus.length > 0) { // 创建子菜单的ul容器 const childUl = $('<ul class="goksel"></ul>'); // 遍历子菜单,添加到ul里 childMenus.forEach(childMenu => { const childLi = $(` <li> <a href="/Reports/ProductBOM.aspx"> <span class="lang" data-key="${childMenu.MenuID}">${childMenu.MenuName}</span> </a> </li> `); childUl.append(childLi); }); // 将子菜单ul添加到对应的父菜单li中 parentLi.append(childUl); } }); }
额外说明
- 如果子菜单的跳转链接不是固定的
/Reports/ProductBOM.aspx,可以从菜单数据里取对应的字段(比如childMenu.MenuUrl),替换掉固定链接即可。 - 这种分组处理的方式,不管菜单层级有多少(如果后续需要更深层级),都可以通过递归的方式扩展,但当前需求是两级菜单,这样写就足够清晰了。
内容的提问来源于stack exchange,提问作者Göksel Colak
相关产品推荐
相关产品推荐

