WordPress自定义导航栏JS问题:点击外部无法关闭下拉菜单
解决WordPress导航栏点击外部关闭下拉菜单的问题
问题分析
原代码存在两个核心问题:
- 窗口点击事件逻辑错误,错误遍历子菜单的类列表而非所有子菜单
- 菜单项点击事件未阻止冒泡,导致点击菜单时会触发窗口点击事件,干扰下拉菜单的显示切换
修正后的代码
JavaScript 代码
const menuItems = document.querySelectorAll('.menu-item-has-children'); const subMenus = document.querySelectorAll('.sub-menu'); const navbar = document.getElementById('navbarNavDropdown'); // 处理菜单项点击事件 menuItems.forEach((item, index) => { item.addEventListener('click', (e) => { // 阻止事件冒泡,避免触发window的点击事件 e.stopPropagation(); // 切换当前子菜单的显示状态 subMenus[index].classList.toggle('show'); // 关闭其他所有子菜单 subMenus.forEach((subMenu, subIndex) => { if (subIndex !== index) { subMenu.classList.remove('show'); } }); }); }); // 处理窗口点击事件,点击导航外部关闭所有子菜单 window.addEventListener('click', () => { subMenus.forEach(subMenu => { subMenu.classList.remove('show'); }); }); // 额外处理:点击导航内部非菜单项区域,也关闭所有子菜单(可选) navbar.addEventListener('click', (e) => { if (!e.target.closest('.menu-item-has-children')) { subMenus.forEach(subMenu => { subMenu.classList.remove('show'); }); } });
HTML 结构(保持原结构不变)
<div id="navbarNavDropdown" class="collapse navbar-collapse"> <div class="menu-main-nav-container"> <ul id="menu-main-nav" class="menu"> <li id="menu-item-1973" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-1973" data-ol-has-click-handler=""> <a>Bookmakers</a> <ul class="sub-menu"> <li id="menu-item-1974" class="menu-item menu-item-type-post_type menu-item-object-operator menu-item-1974"><a href="http://localhost:10018/operators/toto/">toto</a></li> <li id="menu-item-1975" class="menu-item menu-item-type-post_type menu-item-object-operator menu-item-1975"><a href="http://localhost:10018/operators/ze-turf/">Ze Turf</a></li> <li id="menu-item-1976" class="menu-item menu-item-type-post_type menu-item-object-operator menu-item-1976"><a href="http://localhost:10018/operators/fair-play/">Fair play</a></li> <li id="menu-item-1977" class="menu-item menu-item-type-post_type menu-item-object-operator menu-item-1977"><a href="http://localhost:10018/operators/bingo-ball/">Bingo Ball</a></li> <li id="menu-item-1978" class="menu-item menu-item-type-post_type menu-item-object-operator menu-item-1978"><a href="http://localhost:10018/operators/ggpoker/">GGpoker</a></li> <li id="menu-item-1979" class="menu-item menu-item-type-post_type menu-item-object-operator menu-item-1979"><a href="http://localhost:10018/operators/holland-casino/">Holland Casino</a></li> <li id="menu-item-1980" class="menu-item menu-item-type-post_type menu-item-object-operator menu-item-1980"><a href="http://localhost:10018/operators/betcity/">betCity</a></li> <li id="menu-item-1981" class="menu-item menu-item-type-post_type menu-item-object-operator menu-item-1981"><a href="http://localhost:10018/operators/bet365/">bet365</a></li> </ul> </li> <li id="menu-item-1982" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-1982"><a href="#">Bonuses</a></li> <li id="menu-item-1983" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-1983"><a href="#">Strategies</a></li> <li id="menu-item-1984" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-1984"><a href="#">Articles</a></li> <li id="menu-item-2063" class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-2063"><a href="http://localhost:10018/category/news/">News</a></li> <li id="menu-item-1985" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-1985" data-ol-has-click-handler=""> <a>Tools</a> <ul class="sub-menu"> <li id="menu-item-1986" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-1986"><a href="#">System Bets Calculator</a></li> <li id="menu-item-1987" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-1987"><a href="#">Injured and suspended</a></li> <li id="menu-item-1988" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-1988"><a href="#">Glossary</a></li> </ul> </li> <li id="menu-item-1990" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-1990" data-ol-has-click-handler=""> <a>Betting Tips</a> <ul class="sub-menu"> <li id="menu-item-2010" class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-2010"><a href="http://localhost:10018/category/betting-categories/bundesliga/">Bundesliga</a></li> <li id="menu-item-2011" class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-2011"><a href="http://localhost:10018/category/betting-categories/champions-league/">Champions League</a></li> <li id="menu-item-2012" class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-2012"><a href="http://localhost:10018/category/betting-categories/eredvisie/">Eredvisie</a></li> <li id="menu-item-2013" class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-2013"><a href="http://localhost:10018/category/betting-categories/europa-league/">Europa League</a></li> <li id="menu-item-2014" class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-2014"><a href="http://localhost:10018/category/betting-categories/premier-league/">Premier League</a></li> <li id="menu-item-2015" class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-2015"><a href="http://localhost:10018/category/betting-categories/primera-divison/">Primera Divison</a></li> <li id="menu-item-2016" class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-2016"><a href="http://localhost:10018/category/betting-categories/serie-a/">Serie A</a></li> </ul> </li> <li id="menu-item-1991" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-1991"><a href="#">Something</a></li> </ul> </div> </div>
关键修改点
- 阻止事件冒泡:在菜单项点击事件中调用
e.stopPropagation(),避免点击菜单时触发window的点击事件,确保下拉菜单正常切换。 - 修复窗口点击逻辑:直接遍历所有子菜单移除
show类,实现点击外部关闭所有下拉菜单。 - 优化遍历方式:使用
forEach替代传统for循环,代码更简洁易读。 - 可选导航内部处理:点击导航栏内非下拉菜单项区域时,自动关闭所有下拉菜单,提升用户体验。
内容的提问来源于stack exchange,提问作者Jovan Jovanovic
相关产品推荐
相关产品推荐

