手风琴式(Accordion-style)菜单子菜单功能异常求助
解决手风琴菜单子菜单点击异常的问题
嘿,我看了你的手风琴菜单代码,问题根源是事件冒泡——当你点击子菜单时,点击事件会向上传递到父级的.accordion元素,触发了它的折叠/展开逻辑,所以才会出现子菜单无法展示内容、还直接关闭父div的情况。下面给你两种修复方案,选一种适合你的就行:
方案一:在父级点击事件中区分目标元素
这种方法不需要单独给子菜单绑定事件,直接在父级的点击处理逻辑里判断点击的是不是子菜单部分,避免触发父级折叠:
document.querySelectorAll('.accordion').forEach(item => { item.addEventListener('click', function(e) { // 检查点击目标是否属于子菜单(这里假设子菜单容器类是.submenu) const isSubmenuClick = e.target.closest('.submenu'); if (isSubmenuClick) { // 阻止事件冒泡到父级,避免关闭父div e.stopPropagation(); // 处理子菜单的展开/折叠逻辑 const subContent = isSubmenuClick.querySelector('.submenu-content'); subContent.style.maxHeight = subContent.style.maxHeight ? null : subContent.scrollHeight + 'px'; return; } // 父级手风琴的原有逻辑 this.classList.toggle('active'); const content = this.nextElementSibling; content.style.maxHeight = content.style.maxHeight ? null : content.scrollHeight + 'px'; }); });
方案二:给子菜单单独绑定事件(更清晰)
把父级和子菜单的逻辑分开处理,结构更清晰,也更容易维护:
// 处理父级手风琴的折叠/展开 document.querySelectorAll('.accordion').forEach(accordion => { accordion.addEventListener('click', function() { this.classList.toggle('active'); const content = this.nextElementSibling; content.style.maxHeight = content.style.maxHeight ? null : content.scrollHeight + 'px'; }); }); // 处理子菜单的点击逻辑 document.querySelectorAll('.submenu').forEach(submenu => { submenu.addEventListener('click', function(e) { // 关键:阻止事件冒泡到父级的accordion元素 e.stopPropagation(); // 展开/折叠子菜单内容 const subContent = this.querySelector('.submenu-content'); subContent.style.maxHeight = subContent.style.maxHeight ? null : subContent.scrollHeight + 'px'; }); });
补充CSS样式
不管用哪种方案,都需要给子菜单内容加上默认隐藏的样式,确保初始状态是收起的:
.submenu-content { max-height: 0; overflow: hidden; transition: max-height 0.2s ease-out; background-color: #f1f1f1; /* 可选,和父级内容区分开 */ padding-left: 20px; /* 可选,缩进子菜单内容 */ }
这样修改后,点击子菜单就只会触发自身的展开/折叠,不会再影响父级的手风琴状态了。
内容的提问来源于stack exchange,提问作者Brannon R Laveder
相关产品推荐
相关产品推荐

