下拉菜单按钮异常:仅首个按钮可触发JS事件其余失效
修复多下拉菜单仅第一个生效的问题
问题原因
原JavaScript代码中使用document.querySelector('.drop-menu-btn')只会返回页面中第一个匹配该类名的元素,因此只有第一个下拉按钮绑定了点击事件,其余按钮无法触发交互。
解决方案
需要获取所有下拉按钮元素,逐个为它们绑定点击事件,并通过DOM元素的层级关系找到对应按钮的下拉菜单和图标,而非全局选择第一个元素。
修改后的JavaScript代码
// 获取所有下拉按钮 const dropMenuBtns = document.querySelectorAll('.drop-menu-btn'); // 遍历每个按钮,绑定点击事件 dropMenuBtns.forEach(btn => { // 找到当前按钮对应的下拉菜单(按钮的下一个兄弟元素) const dropMenu = btn.nextElementSibling; // 找到当前按钮内的图标 const icon = btn.querySelector('i'); btn.addEventListener('click', (e) => { // 阻止默认跳转行为 e.preventDefault(); // 切换下拉菜单的active类 dropMenu.classList.toggle('active'); // 切换图标的rotated类 icon.classList.toggle('rotated'); }); });
原HTML代码(无需修改)
<nav class="nav-bar"> <div class="logo"> <a href="#">Logo</a> </div> <ul class="nav-links"> <li><a href="#">Home</a></li> <li> <a class="drop-menu-btn" href="#">Product <i class="fa fa-chevron-down" aria-hidden="true"></i></a> <ul class="drop-menu"> <li class="drop-menu-link"><a href="#">link</a></li> <li class="drop-menu-link"><a href="#">link</a></li> <li class="drop-menu-link"><a href="#">link</a></li> </ul> </li> <li><a href="#">News</a></li> <li><a href="#">Tips</a></li> <li> <a class="drop-menu-btn" href="#">About Us <i class="fa fa-chevron-down" aria-hidden="true"></i></a> <ul class="drop-menu"> <li class="drop-menu-link"><a href="#">link</a></li> <li class="drop-menu-link"><a href="#">link</a></li> <li class="drop-menu-link"><a href="#">link</a></li> </ul> </li> <li> <a class="drop-menu-btn" href="#">Gallery <i class="fa fa-chevron-down" aria-hidden="true"></i></a> <ul class="drop-menu"> <li class="drop-menu-link"><a href="#">link</a></li> <li class="drop-menu-link"><a href="#">link</a></li> <li class="drop-menu-link"><a href="#">link</a></li> </ul> </li> <li><a href="#">Contact Us</a></li> </ul> </nav>
原CSS代码(无需修改)
:root { --greenColor:#409a4d; --whiteColor: #ffffff; --blackColor:#212121; } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: "Open Sans"; } a { text-decoration: none; } ul { list-style: none; } /* nav bar */ .nav-bar { display: flex; align-items: center; justify-content: space-between; width: 100%; filter: drop-shadow(0px 3px 7px rgba(0,0,0,0.07)); background-color: #ffffff; -webkit-filter: drop-shadow(0px 3px 7px rgba(0,0,0,0.07)); padding: 14px 20px; } .nav-bar .logo a { color: var(--greenColor); font-weight: 500; font-size: 25px; } .nav-bar .nav-links { display: flex; align-items: center; gap: 50px; } .nav-bar .nav-links li a { font-size: 18px; font-weight: 400; color: var(--blackColor); transition:all 3s ease; -webkit-transition:all 3s ease; -moz-transition:all 3s ease; -ms-transition:all 3s ease; -o-transition:all 3s ease; position: relative; } .nav-bar .nav-links li { position: relative; display: block; } .nav-bar .nav-links li .drop-menu { display: none; position: absolute; top: 43px; text-align: center; filter: drop-shadow(0px 3px 7px rgba(0,0,0,0.07)); background-color: #ffffff; -webkit-filter: drop-shadow(0px 3px 7px rgba(0,0,0,0.07)); animation: drop .3s; -webkit-animation: drop .3s; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; } .nav-bar .nav-links li .drop-menu.active { display: block; width: 100%; height: 180px; } .nav-bar .nav-links li .drop-menu-btn i.rotated { transform: rotate(180deg); -webkit-transform: rotate(180deg); -moz-transform: rotate(180deg); -ms-transform: rotate(180deg); -o-transform: rotate(180deg); } .nav-bar .nav-links li .drop-menu >li { margin-bottom: 12px; }
关键说明
querySelectorAll会返回所有匹配选择器的元素节点列表,通过forEach遍历可给每个按钮绑定事件。- 使用
nextElementSibling获取当前按钮的下一个兄弟元素(即对应下拉菜单),确保每个按钮只控制自己的下拉菜单。 - 调用
e.preventDefault()阻止<a>标签默认跳转行为,避免页面锚点跳转。
内容的提问来源于stack exchange,提问作者mohamed tu
相关产品推荐
相关产品推荐

