为多级<div>自动循环设置data-level属性的专业代码需求
自动为多级菜单的
<div>设置data-level属性的JavaScript方案 你的手动写法确实会在菜单层级增加时变得非常繁琐,而且扩展性极差。这里有两种更优雅的解决方案,能够自动适配任意层级的菜单,不管是5级还是20级都能轻松处理:
方案一:递归遍历(简洁直观)
递归是处理嵌套结构最自然的方式,我们从顶级菜单开始,逐层往下遍历每一级子菜单,自动计算并设置层级:
// 获取顶级菜单容器 const navMenu = document.querySelector('.nav-menu'); // 递归函数:处理当前层级的子菜单,并继续遍历下一级 function setSubMenuLevel(parentElement, currentLevel) { // 在当前父元素范围内,找到所有直接属于li的子菜单div const subMenus = parentElement.querySelectorAll('li > div.sub-menu'); subMenus.forEach(subMenu => { // 为当前子菜单设置data-level subMenu.setAttribute('data-level', currentLevel); // 递归处理下一级子菜单,层级加1 setSubMenuLevel(subMenu, currentLevel + 1); }); } // 启动递归,从顶级ul开始,初始层级设为1 setSubMenuLevel(navMenu.querySelector('ul'), 1);
为什么这个方案更好?
- 无限层级支持:不管菜单嵌套多少层,递归都会自动遍历到最底层,再也不用手动添加新的选择器和循环
- 代码简洁可维护:只需要一个函数,逻辑清晰,后续修改或扩展都很方便
- DOM查询更高效:通过父元素范围查询,避免全局多次查找DOM元素,性能更优
方案二:迭代遍历(稳妥无栈溢出风险)
如果你的菜单层级特别深(比如超过100级),递归可能会触发浏览器的调用栈溢出,这时候可以用队列实现迭代遍历,更稳妥:
const navMenu = document.querySelector('.nav-menu'); // 初始化队列,存入顶级ul和对应的初始层级1 const queue = [{ element: navMenu.querySelector('ul'), level: 1 }]; while (queue.length > 0) { // 取出队列中的第一个元素 const { element, level } = queue.shift(); // 找到当前层级下的所有子菜单div const subMenus = element.querySelectorAll('li > div.sub-menu'); subMenus.forEach(subMenu => { subMenu.setAttribute('data-level', level); // 找到子菜单里的ul,加入队列准备处理下一级 const nextLevelUl = subMenu.querySelector('ul'); if (nextLevelUl) { queue.push({ element: nextLevelUl, level: level + 1 }); } }); }
验证效果
运行任意一种方案后,你的菜单结构里的每个.sub-menu div都会被自动设置正确的data-level属性:
- 第一级子菜单(menu1的子菜单)→
data-level="1" - 第二级子菜单(menu1-1的子菜单)→
data-level="2" - 第三级子菜单(menu1-1-1的子菜单)→
data-level="3" - 以此类推,更深的层级也会自动匹配
内容的提问来源于stack exchange,提问作者Mahdi Khaleghi
相关产品推荐
相关产品推荐

