JavaScript导航栏下拉菜单点击内容区消失问题修复咨询
解决方案
问题原因
你当前绑定在window上的点击事件逻辑存在缺陷:只要页面触发点击,就会先移除所有下拉菜单的show类,仅当点击目标是下拉按钮时才重新给对应菜单加show类。当你点击下拉菜单内部区域时,点击事件冒泡到window触发该逻辑,而此时点击目标不是.dropbtn,因此菜单会被直接隐藏。
修改步骤
- 移除所有下拉按钮上的
onclick属性,避免和全局点击监听逻辑冲突,原有代码里的my1Function、my2Function、my3Function也可以直接删除,不再需要。 - 修改window的点击事件监听逻辑,增加点击区域判断:只有当点击目标既不是下拉按钮,也不在已展开的下拉菜单内部时,才隐藏所有下拉菜单。
修改后的完整代码
<!DOCTYPE HTML> <html> <head> <style> .navbar { width: 100%; padding: 0 10% 0 10%; box-shadow: 0 2px 5px 0 rgba(0,0,0,0.16),0 2px 10px 0 rgba(0,0,0,0.12); z-index: 4; position: relative; } .navbar a { padding:15px 0px; text-align: center; text-decoration: none; float: left; font-weight: 200; } .dropbtn { font-size: 16px; border: none; outline: none; padding: 21.5px 20px; background-color: inherit; margin: 0; cursor: pointer; font-weight: bolder; color: #2d3436; } .dropdown { float: left; } .dropdown-content { display: none; position: absolute; background-color: #fff; min-width: 460px; box-shadow: 0 2px 5px 0 rgba(0,0,0,0.16),0 2px 10px 0 rgba(0,0,0,0.12); height: 450px; border-radius: 3.5px; z-index: 1; border-top: 2px solid #000; } .show{display:block} </style> </head> <body> <div class="navbar"> <div class="dropdown"> <button class="dropbtn dropbtn1">Marketing</button> <div id="myDropdown1" class="dropdown-content dropdown-content1"> <!-- 菜单内容 --> </div> </div> <div class="dropdown"> <button class="dropbtn dropbtn2">Development</button> <div id="myDropdown2" class="dropdown-content dropdown-content2"> <!-- 菜单内容 --> </div> </div> <div class="dropdown"> <button class="dropbtn dropbtn3">Others</button> <div id="myDropdown3" class="dropdown-content dropdown-content2"> <!-- 菜单内容 --> </div> </div> </div> <script> window.addEventListener('click', function(event) { // 判断点击目标是否是下拉按钮 const isDropBtn = event.target.matches('.dropbtn'); // 判断点击目标是否在展开的下拉菜单内部 const isInDropdown = event.target.closest('.dropdown-content') !== null; // 如果既不是点按钮也不是点菜单内部,才关闭所有菜单 if (!isDropBtn && !isInDropdown) { const dropdownContents = document.querySelectorAll('.dropdown-content') dropdownContents.forEach(content => { content.classList.remove('show'); }); } // 如果点的是下拉按钮,切换对应菜单的显示状态 if (isDropBtn) { const targetDropdown = event.target.nextElementSibling; // 先关闭其他所有菜单 document.querySelectorAll('.dropdown-content').forEach(content => { if (content !== targetDropdown) content.classList.remove('show'); }); // 切换当前菜单的显示状态 targetDropdown.classList.toggle('show'); } }) </script> </body> </html>
优化说明
修改后的逻辑还额外增加了点击其他下拉按钮时自动关闭已展开菜单的交互,更符合常规下拉菜单的使用体验。
内容的提问来源于stack exchange,提问作者user17512898
相关产品推荐
相关产品推荐

