用事件冒泡实现多级菜单收起,核心是将点击监听器绑定到父容器,通过target判断点击目标是否为开关按钮或菜单外部,再切换对应子菜单active状态并阻止内部元素冒泡,配合css的max-height过渡实现平滑动画。

用事件冒泡实现多级菜单收起,核心是把“收起”逻辑统一绑定在父容器上,利用点击事件从子元素向上冒泡的特性,判断点击目标是否为菜单项或开关按钮,再决定是否收起对应层级——避免给每个菜单项单独绑事件,也省去手动管理多个事件监听器的麻烦。
绑定事件到最外层菜单容器
把 click 事件监听器只加在多级菜单的根元素(比如 <nav class="menu"></nav> 或 <div id="main-menu">)上。所有子菜单、标题、链接的点击都会冒泡到这里处理:<font color="#666"><pre class="brush:php;toolbar:false;">const menuContainer = document.getElementById('main-menu');
menuContainer.addEventListener('click', handleMenuClick);
</pre></font><h3>在事件处理器中识别点击目标并收起对应层级</h3>
<p>在 <code>handleMenuClick 中,检查 event.target 是不是某个可展开/收起的菜单触发器(如带 data-toggle="submenu" 的按钮),或者是不是非当前展开菜单的其他区域(用于点击空白处收起):
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 若点击的是某个子菜单的开关按钮(如
<button class="submenu-toggle"></button>),则切换该子菜单的open状态(添加/移除active类或aria-expanded属性) - 若点击的是菜单外部(
event.target === menuContainer),或点击的是其他子菜单项,则先收起所有已展开的子菜单(可选:保留当前点击项的上级) - 用
closest()快速定位最近的菜单上下文,例如:target.closest('.submenu')找到被操作的子菜单块
阻止内部交互意外触发收起
有些区域(如输入框、下拉选择、子菜单内的链接)点击时不希望收起菜单,需在它们的事件中调用 event.stopPropagation():
// 子菜单里的搜索框不触发收起
document.querySelectorAll('.submenu input').forEach(input => {
input.addEventListener('click', e => e.stopPropagation());
});
配合 CSS 实现平滑收起动画
仅靠 JS 切换类名还不够,要让收起有过渡效果,CSS 需配合设置 max-height 或 height 的 transition,并用 overflow: hidden 隐藏溢出内容:
.submenu {
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease-out;
}
.submenu.active {
max-height: 500px; /* 设为足够容纳内容的值,或用 JS 动态计算 */
}










