如何用原生JS实现多级菜单打开时自动折叠其他已展开子菜单
你需要在子菜单的点击事件中新增折叠同级其他已展开子菜单的逻辑,仅需修改submenuToggle函数即可实现需求,修改后的完整JS代码如下:
/* toggle click function for submenus */ slideToggle=(el)=> { let cs = window.getComputedStyle(el).display; if(cs==="none") { el.style.display="block"; } else { el.style.display="none"; } } /* detecting menus which has submenus */ submenuDetect=()=> { let li = document.querySelectorAll(".main-navigation-content > ul li"); /* adding a class "has-submenu" for menu which has sublevel menu */ li.forEach((item)=>{ let ul = item.querySelector("ul"); if(ul){ item.classList.add("has-submenu"); ul.classList.add("submenu-content"); /* adding icon */ let iconElement = document.createElement("span"); iconElement.setAttribute("class","down-arrow-icon submenu-trigger"); item.querySelector("a").insertAdjacentElement("afterend", iconElement); } }); } /* assign toggle function to menu which has submenus */ submenuToggle=()=>{ /* find all menu which has submenus and making toggle */ let submenuTrigger = document.querySelectorAll(".has-submenu > a"); submenuTrigger.forEach((item)=>{ item.addEventListener("click",(e)=>{ e.preventDefault(); const currentLi = e.target.parentElement; const submenuContent = currentLi.querySelector('.submenu-content'); // 折叠当前菜单的所有同级已展开子菜单 const siblingLis = Array.from(currentLi.parentElement.children); siblingLis.forEach(li => { if(li !== currentLi && li.classList.contains('has-submenu')){ li.querySelector('.submenu-content').style.display = 'none'; } }) // 切换当前点击的子菜单状态 slideToggle(submenuContent); }) }); } /* calling submenu detect function and slidetoggle function */ submenuDetect(); submenuToggle();
逻辑说明
- 每次点击带子菜单的导航项时,先获取当前导航项的所有同级兄弟节点
- 遍历兄弟节点,只要不是当前点击的节点且带有子菜单,就直接折叠它的子菜单
- 最后再切换当前点击的子菜单的展开/折叠状态,同时保留点击已展开菜单直接折叠的交互
该逻辑支持多级菜单场景,只会折叠同一层级的其他子菜单,不会影响父级或更深层级的菜单状态,符合常规多级导航的交互逻辑。
内容的提问来源于stack exchange,提问作者Ren Jitsm
相关产品推荐
相关产品推荐

