如何用JavaScript实现仅单个下拉菜单展开的功能
实现单一展开的下拉菜单解决方案
问题描述
我用HTML、CSS和JavaScript制作了一个下拉菜单。点击带有filter-dropdown-btn类的元素时,会为其后续的filter-dropdown-content类元素添加active-dropdown类以展开菜单;同时为箭头图标添加active-chevron类使其旋转。
请问如何设置同一时间仅允许一个下拉菜单展开?点击另一个下拉菜单时,之前展开的菜单能自动关闭?
现有代码
HTML
<!-- Font Awesome Kit --> <script src="https://kit.fontawesome.com/d778668bce.js" crossorigin="anonymous" defer></script> <div class="filter__dropdown"> <!-- Dropdown Item --> <div class="dropdown-item"> <button type="button" class="filter-dropdown-btn"> Loan amount <i class="fa-solid fa-chevron-down fa-xs filter-dropdown-icon"></i> </button> <div class="dropdown-content filter-dropdown-content"> <ul> <li> <a href="javascript:">All</a> </li> <hr /> <li> <a href="javascript:">0 - 1000</a> </li> <hr /> <li> <a href="javascript:">1000 - 10000</a> </li> <hr /> <li> <a href="javascript:">10000 - 100000</a> </li> <hr /> <li> <a href="javascript:">100000 - 1000000</a> </li> </ul> </div> </div> <!-- Dropdown Item --> <div class="dropdown-item"> <button type="button" class="filter-dropdown-btn"> Collections <i class="fa-solid fa-chevron-down fa-xs filter-dropdown-icon"></i> </button> <div class="dropdown-content filter-dropdown-content"> <ul> <li> <a href="javascript:">All</a> </li> <hr /> <li> <a href="javascript:">0 - 1000</a> </li> <hr /> <li> <a href="javascript:">1000 - 10000</a> </li> <hr /> <li> <a href="javascript:">10000 - 100000</a> </li> <hr /> <li> <a href="javascript:">100000 - 1000000</a> </li> </ul> </div> </div> <!-- Dropdown Item --> <div class="dropdown-item"> <button type="button" class="filter-dropdown-btn"> Total interest <i class="fa-solid fa-chevron-down fa-xs filter-dropdown-icon"></i> </button> <div class="dropdown-content filter-dropdown-content"> <ul> <li> <a href="javascript:">All</a> </li> <hr /> <li> <a href="javascript:">5 SOL</a> </li> <hr /> <li> <a href="javascript:">10 SOL</a> </li> <hr /> <li> <a href="javascript:">20 SOL</a> </li> <hr /> <li> <a href="javascript:">50 SOL</a> </li> </ul> </div> </div> <!-- Dropdown Item --> <div class="dropdown-item"> <button type="button" class="filter-dropdown-btn"> Return rate <i class="fa-solid fa-chevron-down fa-xs filter-dropdown-icon"></i> </button> <div class="dropdown-content filter-dropdown-content"> <ul> <li> <a href="javascript:">All</a> </li> <hr /> <li> <a href="javascript:">1%</a> </li> <hr /> <li> <a href="javascript:">10%</a> </li> <hr /> <li> <a href="javascript:">20%</a> </li> <hr /> <li> <a href="javascript:">40%</a> </li> </ul> </div> </div> <!-- Dropdown Item --> <div class="dropdown-item"> <button type="button" class="filter-dropdown-btn"> Loan duration <i class="fa-solid fa-chevron-down fa-xs filter-dropdown-icon"></i> </button> <div class="dropdown-content filter-dropdown-content"> <ul> <li> <a href="javascript:">All</a> </li> <hr /> <li> <a href="javascript:">2 days</a> </li> <hr /> <li> <a href="javascript:">4 days</a> </li> <hr /> <li> <a href="javascript:">10 days</a> </li> <hr /> <li> <a href="javascript:">More than 20 days</a> </li> </ul> </div> </div> </div>
CSS
body { background-color: #100420; } ul { padding: 0; } li { list-style-type: none; } a { text-decoration: none; color: white; } .dropdown-item { position: relative; } .dropdown-content { position: absolute; display: none; box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2); z-index: 2; top: 125%; background: #342a41; width: auto; border-radius: 10px; transform: translateX(10%); min-width: 150px; } .dropdown-content::before { content: ""; position: absolute; top: -10px; left: 50%; transform: translateX(-50%); border: 5px solid transparent; border-bottom: 5px solid #342a41; } .dropdown-content li { padding-inline: 1rem; margin-block: 0.75rem; color: #fff; } .dropdown-content hr { border-top: 0.1rem solid rgba(255, 255, 255, 0.1); border-bottom: 0; border-left: 0; border-right: 0; } .filter__dropdown { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 1rem; color: #fff; } .filter__dropdown .filter-dropdown-btn { display: flex; align-items: center; justify-content: center; padding: 0.75rem 1rem; font-size: 1rem; border: none; border-radius: 15px; color: #fff; background-color: rgba(238, 225, 255, 0.13); cursor: pointer; gap: 1rem; } .filter__dropdown .filter-dropdown-btn:hover { background-color: rgba(238, 225, 255, 0.2); } .dropdown-content.active-dropdown { display: block; } .filter-dropdown-icon.active-chevron { transform: rotate(180deg); }
JavaScript
let filterDropdown = document.querySelectorAll(".filter-dropdown-btn"); filterDropdown.forEach((item) => { item.addEventListener("click", function() { // remove .active-dropdown from all dropdowns let dropdowns = document.querySelectorAll(".filter-dropdown-content"); dropdowns.forEach((item) => { item.classList.remove("active-dropdown"); }); // remove .active-chevron from all buttons let dropdownIcons = document.querySelectorAll(".filter-dropdown-icon"); dropdownIcons.forEach((item) => { item.classList.remove("active-chevron"); }); let dropdownContent = this.nextElementSibling; dropdownContent.classList.toggle("active-dropdown"); let dropdownIcon = this.children[0]; dropdownIcon.classList.toggle("active-chevron"); }); });
解决方案优化
你的现有代码已经实现了基础的单一展开逻辑,但存在小问题:点击当前已展开的菜单按钮时,它会先关闭再重新打开,无法直接切换关闭状态。可以通过判断当前菜单的激活状态优化逻辑,代码如下:
let filterDropdown = document.querySelectorAll(".filter-dropdown-btn"); filterDropdown.forEach((item) => { item.addEventListener("click", function() { // 获取当前按钮对应的下拉内容和图标 const currentContent = this.nextElementSibling; const currentIcon = this.children[0]; // 判断当前菜单是否已经展开 const isActive = currentContent.classList.contains("active-dropdown"); // 统一关闭所有下拉菜单并重置箭头图标 document.querySelectorAll(".filter-dropdown-content").forEach(content => { content.classList.remove("active-dropdown"); }); document.querySelectorAll(".filter-dropdown-icon").forEach(icon => { icon.classList.remove("active-chevron"); }); // 仅在当前菜单未展开时,才展开它 if (!isActive) { currentContent.classList.add("active-dropdown"); currentIcon.classList.add("active-chevron"); } }); });
优化说明
- 先获取当前点击按钮对应的下拉内容和图标,判断其是否处于激活状态
- 统一关闭所有下拉菜单并重置箭头图标
- 根据判断结果,仅在当前菜单原本关闭时展开它;若原本展开,则保持关闭状态
- 既实现了单一展开的需求,也支持点击当前展开的菜单按钮将其关闭
内容的提问来源于stack exchange,提问作者jeremy0x
相关产品推荐
相关产品推荐

