导航栏多下拉按钮优化:仅显示当前激活的下拉菜单内容
解决多下拉菜单同时显示的问题
问题原因
你当前的代码逻辑中,点击下拉按钮时仅切换对应菜单的显示状态,并未处理其他已打开的菜单;而window.onclick的关闭逻辑仅在点击非.dropbtn元素时触发,导致点击新按钮时旧菜单不会自动关闭。
解决方案
修改myFunction函数,在切换当前菜单状态前,先关闭所有其他已打开的下拉菜单。
修改后的JavaScript代码
function myFunction(num) { // 获取所有下拉菜单元素 const dropdowns = document.getElementsByClassName("dropdown-content"); // 遍历关闭所有非当前目标的已打开菜单 for (let i = 0; i < dropdowns.length; i++) { const currentDropdown = dropdowns[i]; if (currentDropdown.id !== `myDropdown${num}` && currentDropdown.classList.contains('show')) { currentDropdown.classList.remove('show'); } } // 切换当前目标菜单的显示状态 document.getElementById(`myDropdown${num}`).classList.toggle("show"); } window.onclick = function(event) { if (!event.target.matches('.dropbtn')) { const dropdowns = document.getElementsByClassName("dropdown-content"); for (let i = 0; i < dropdowns.length; i++) { const openDropdown = dropdowns[i]; if (openDropdown.classList.contains('show')) { openDropdown.classList.remove('show'); } } } }
代码说明
- 关闭其他菜单:在处理当前菜单前,遍历所有下拉菜单,关闭那些已经打开且不是当前目标的菜单
- 切换当前菜单:使用
toggle保持原有的点击切换功能——点击已打开的按钮会关闭菜单,点击未打开的按钮会打开(同时关闭其他菜单)
可选优化:点击按钮总是打开当前菜单
如果希望点击按钮时直接打开对应菜单(不管之前是否打开),可以将toggle替换为add,并移除跳过当前菜单的判断:
function myFunction(num) { const dropdowns = document.getElementsByClassName("dropdown-content"); // 关闭所有下拉菜单 for (let i = 0; i < dropdowns.length; i++) { dropdowns[i].classList.remove('show'); } // 打开当前目标菜单 document.getElementById(`myDropdown${num}`).classList.add('show'); }
保留原有HTML和CSS
你的HTML结构和CSS样式无需修改,直接使用即可:
<link rel="stylesheet" href="https://maxst.icons8.com/vue-static/landings/line-awesome/line-awesome/1.3.0/css/line-awesome.min.css"> <header> <div class="header-content"> <div class="dropdown"> <a> <div onclick="myFunction(1)" href="#" class="notification dropbtn las la-envelope"></div> <span onclick="myFunction(1)" class="badge dropbtn">4</span> </a> <div id="myDropdown1" class="dropdown-content"> <div class="arrow_box"> <div class="header-dropdown"> <ul> <li><a href=""><small>Message content</small></a></li> <li><a href=""><small>Message content</small></a></li> </ul> </div> </div> </div> </div> <div class="dropdown"> <a> <div onclick="myFunction(2)" href="#" class="notification dropbtn las la-bell"></div> <span onclick="myFunction(2)" class="badge dropbtn">8</span> </a> <div id="myDropdown2" class="dropdown-content"> <div class="arrow_box"> <div class="header-dropdown"> <ul> <li><a href=""><span class="las la-question"><small>FAQ</small></span></a></li> <li><a href=""><span class="las la-user"><small>Profile</small></span></a></li> <li><a href=""><span class="las la-cog"><small>Settings</small></span></a></li> <li><a href=""><span class="las la-sign-out-alt"><small>Log out</small></span></a></li> </ul> </div> </div> </div> </div> </div> </header>
.ul { } header { position: fixed; right: 0; top: 0; left: 0; z-index: 100; height: 60px; box-shadow: 0px 5px 5px -5px rgb(0 0 0 /10%); background: #4891c4;; color: #ffffff; transition: left 300ms; } .header-content { position: relative; top: 0; width: 200px; height: 60px; float: right; align-items: center; justify-content: center; } .header-content, .header-menu { display: flex; align-items: center; } .header-content { justify-content: space-between; padding: 0rem 1rem; } .header-content label:first-child span { font-size: 1.3rem; } .header-content label { cursor: pointer; } .arrow_box { top: 10px; position: relative; border: 1px solid #aaa; /*set border colour here*/ width: 300px; height: auto; background-color: #d6eef9; /*set menu container background color here*/ border-radius: 3px; -webkit-filter: drop-shadow(0 1px 10px rgba(113, 158, 206, 0.8)); /*set shadow colour and size here*/ -moz-box-shadow: 0 1px 10px rgba(113, 158, 206, 0.8); filter: drop-shadow(0 1px 10px rgba(113, 158, 206, 0.8)); } .arrow_box:after, .arrow_box:before { bottom: 100%; border: solid transparent; content: " "; height: 0; width: 0; position: absolute; pointer-events: none; } .arrow_box:after { border-color: rgba(255, 255, 255, 0); border-bottom-color: #d6eef9; border-width: 10px; right: 8px; margin-right: 0px; } .dropdown { display: flex; height: 40px; width: 40px; border-radius: 50%; position: relative; justify-content: center; align-items: center; margin-right: 1rem; } .dropdown-content { display: none; position: absolute; min-width: 160px; overflow: none; z-index: 1; right: 0; margin-right: 0rem; top: calc(100% + 0rem); } .header-dropdown { background-color: #d6eef9; } .header-dropdown ul li:hover { background: #d8e2ec; } .header-dropdown ul { list-style-type: none; padding: 0; text-align: center; } .header-dropdown a { text-decoration: none; color: var(--menu-color); display: block; padding: 0.5rem 0rem 0.5rem 1rem; /* control menu height here */ text-align: left; /* control menu text align here center, left or right */ } .header-dropdown a span { min-height: 15px; display: inline-flex; align-items: center; font-size: 1.7rem; margin: 0rem 0.5rem 0rem 0.5rem !important; } .header-dropdown a span, .header-dropdown a small { color: #327091; } .header-dropdown a small { font-size: 0.95rem; /* Sidebar font size */ font-weight: normal; margin: 0rem 1rem 0rem 1rem !important; font-family: 'Open Sans', sans-serif; } .dropbtn { border: none; cursor: pointer; } .show { display: block; } .notification { display: flex; height: 30px; width: 30px; border-radius: 50%; position: relative; cursor: pointer; color: white; padding: 1px; font-size: 1.8rem; justify-content: center; align-items: center; } .badge { display: flex; position: absolute; background: red; height: 7px; width: 7px; justify-content: center; align-items: center; border-radius: 50%; right: -7px; top: -7px; padding: 8px; color: #fff; font-size: .8rem; font-weight: 500; }
内容的提问来源于stack exchange,提问作者Eng Khalid Abdi
相关产品推荐
相关产品推荐

