layui 2.x 的 layui.nav 不支持手风琴,需手动监听 .layui-nav-item > a 点击事件,移除兄弟项的 layui-nav-itemed 类并切换当前子菜单显隐;layui 3.x 则原生支持 accordion: true 的 tree 组件。
layui 2.x 中 layui.nav 不支持手风琴,得自己加逻辑
layui 2.x 的 layui.nav 组件本身没有内置「展开一个、收起其余」的手风琴行为,它默认是独立开关。你点开 a,再点开 b,a 还开着——这不是 bug,是设计如此。要实现手风琴,必须监听点击,手动控制其他子菜单的 layui-nav-itemed 类状态。
常见错误现象:layui-nav 嵌套了 layui-nav-child,但所有子菜单能同时展开;或者用了 layui-nav-tree 却发现折叠/展开全靠点击图标,不响应菜单项文字点击。
- 只对带
layui-nav-item的父级菜单绑定点击,别误绑到layui-nav-child内部的a - 用
$(this).next('.layui-nav-child')找当前要切换的子菜单,别用find或children错位操作 - 收起其他时,只操作「同级」的
layui-nav-item下的layui-nav-child,避免影响二级以下嵌套(如果存在)
用 jQuery 模拟手风琴:监听 .layui-nav-item > a 点击
这是最轻量、兼容性最好的做法,不依赖 layui 的模块加载机制,也不动原生渲染逻辑。核心就是:点一个,把所有兄弟的 layui-nav-itemed 移除,再给当前加;同时控制对应子菜单的显隐。
使用场景:你已用 layui.use(['element'], ...) 初始化了导航,HTML 结构是标准的 <ul class="layui-nav layui-nav-tree"><li class="layui-nav-item">
<a>菜单</a><dl class="layui-nav-child">...</dl>
</li></ul>。
示例代码片段:
$('.layui-nav-item > a').on('click', function(e) {
e.preventDefault();
var $this = $(this);
var $child = $this.next('.layui-nav-child');
// 收起所有同级子菜单
$this.parent().siblings('.layui-nav-item').removeClass('layui-nav-itemed')
.children('.layui-nav-child').removeClass('layui-nav-child-show');
// 切换当前
$this.parent().toggleClass('layui-nav-itemed');
$child.toggleClass('layui-nav-child-show');
});
注意:layui-nav-child-show 是 layui 2.x 控制显示的类,不是自定义的;如果你用的是 layui 3.x(beta),类名可能变成 layui-show,需按实际检查 DOM。
layui.element 的 nav 事件无法直接实现手风琴
有人试过监听 element.on('nav(side)', ...),发现它只返回被点击的 elem 和 index,不提供当前展开状态,也没法阻止其他项保持展开。这个事件本质是「点击后触发」,不是「展开前拦截」,所以不能靠它做状态同步。
性能影响很小,但容易踩的坑是:在 nav 回调里又去手动 addClass/removeClass,结果和上面 jQuery 方案冲突,造成闪动或状态错乱。
- 不要在
element.on('nav(...)', ...)里操作 DOM 展开/收起逻辑 - 如果用了
element.render('nav')动态重载菜单,记得重新绑定上面的 jQuery 点击事件 - 移动端点击区域小,建议给
.layui-nav-item > a加padding,别只靠文字触发
layui 3.x(Alpha/Beta)的 tree 组件更适合替代方案
如果你项目允许升级到 layui 3.x(目前是 alpha 版本),官方已废弃 nav,转推 tree 组件。它的 showCheckbox: false + accordion: true 就是原生手风琴,且支持右键、异步加载、高亮选中等。
不过要注意:layui 3.x 和 2.x 不兼容,layui.use 的模块名、CSS 类、API 全变了。比如 layui.tree 初始化后,不能再混用 layui.nav 的 HTML 结构。
参数差异关键点:
-
accordion: true开启手风琴(默认false) -
onlyIconControl: true表示只允许点击图标展开,不符合“点文字也展开”的需求,得设为false - 数据格式必须是数组套对象,不能直接复用旧版
layui-nav的 HTML
真正麻烦的不是写法,而是菜单权限动态生成时,2.x 的 HTML 拼接和 3.x 的 JSON 数据驱动思维要彻底切换。这点很多人一开始没意识到。










