You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 09:05:27