同一逻辑的JavaScript下拉切换函数仅部分按钮组生效的问题求助
Hey there! I see exactly what's causing your issue here—let's break it down and fix it together.
The Root Problem
You're assigning window.onclick twice: once in your first function block, then again in the second. When you do window.onclick = function(event) {...}, you're overwriting the previous click handler entirely. That's why only the last one you write works for closing dropdowns when clicking outside—its logic replaces the first one completely.
The Fix: Use addEventListener Instead
Instead of replacing the onclick property directly, use window.addEventListener('click', function(event) {...}) to add multiple click handlers. This way, both sets of dropdown close logic will run when the window is clicked, no matter which order you define them in.
Here's how to update your code:
Updated Function 1
/* 当用户点击按钮时,切换下拉内容的显示/隐藏状态 */ function civilmenuFunction() { document.getElementById("lawsmenudropcivil").classList.toggle("lawsshow"); } // 点击下拉菜单外部时关闭下拉 - 使用addEventListener绑定事件 window.addEventListener('click', function(event) { if (!event.target.matches('.lawsdropbtn')) { var dropdowns = document.getElementsByClassName("lawsdropdown-content"); var i; for (i = 0; i < dropdowns.length; i++) { var openDropdown = dropdowns[i]; if (openDropdown.classList.contains('lawsshow')) { openDropdown.classList.remove('lawsshow'); } } } });
Updated Function 2
function moresearchoptions() { document.getElementById("search-options").classList.toggle("more-search-show"); } // 点击下拉菜单外部时关闭下拉 - 使用addEventListener绑定事件 window.addEventListener('click', function(event) { if (!event.target.matches('.more-search-btn')) { var dropdowns = document.getElementsByClassName("search-options-dropdowncontent"); var i; for (i = 0; i < dropdowns.length; i++) { var openDropdown = dropdowns[i]; if (openDropdown.classList.contains('more-search-show')) { openDropdown.classList.remove('more-search-show'); } } } });
Bonus: Clean Up Redundant Code
Since both blocks do almost the same thing (close a dropdown when clicking outside its trigger button), you can wrap this logic into a reusable function to make your code cleaner and easier to maintain. Here's how that might look:
// 通用的外部点击关闭下拉函数 function closeDropdownOnOutsideClick(buttonSelector, dropdownClass, activeClass) { window.addEventListener('click', function(event) { if (!event.target.matches(buttonSelector)) { const dropdowns = document.getElementsByClassName(dropdownClass); for (let i = 0; i < dropdowns.length; i++) { const openDropdown = dropdowns[i]; if (openDropdown.classList.contains(activeClass)) { openDropdown.classList.remove(activeClass); } } } }); } // 第一组下拉逻辑 function civilmenuFunction() { document.getElementById("lawsmenudropcivil").classList.toggle("lawsshow"); } closeDropdownOnOutsideClick('.lawsdropbtn', 'lawsdropdown-content', 'lawsshow'); // 第二组下拉逻辑 function moresearchoptions() { document.getElementById("search-options").classList.toggle("more-search-show"); } closeDropdownOnOutsideClick('.more-search-btn', 'search-options-dropdowncontent', 'more-search-show');
This way, you don't repeat the same loop logic twice, and if you need to add more dropdowns later, you just call the reusable function with the right selectors and classes.
内容的提问来源于stack exchange,提问作者Ritankar Bhattacharjee

