首页 > 解决方案 > 点击任意位置关闭下拉菜单

问题描述

所以我有下面的代码可以点击下拉菜单并打开它们,但是当我点击另一个下拉菜单时,它不会关闭前一个 - 如何调整我的 JS 代码以关闭前一个下拉菜单并保留当前下拉菜单只开放?

function dropdowns() {
    var dropdowns = document.querySelectorAll('.dropdown:not(.is-hoverable)');

    if (dropdowns.length > 0) {
        dropdowns.forEach(function (el) {
            el.addEventListener('click', function (event) {
                event.stopPropagation();
                el.classList.toggle('is-active');
            });
        });

        document.addEventListener('click', function (event) {
            closeDropdowns();
        });
    }

    function closeDropdowns() {
        dropdowns.forEach(function (el) {
            el.classList.remove('is-active');
        });
    }
}
<link href="https://cdn.jsdelivr.net/npm/bulma@0.8.0/css/bulma.min.css" rel="stylesheet"/>

<div class="dropdown is-clickable">
  <div class="dropdown-trigger">
    <button class="button" aria-haspopup="true" aria-controls="dropdown-menu">
      <span>Dropdown button</span>
      <span class="icon is-small">
        <i class="fas fa-angle-down" aria-hidden="true"></i>
      </span>
    </button>
  </div>
  <div class="dropdown-menu" id="dropdown-menu" role="menu">
    <div class="dropdown-content">
      <a href="#" class="dropdown-item">
        Dropdown item
      </a>
      <a class="dropdown-item">
        Other dropdown item
      </a>
      <a href="#" class="dropdown-item is-active">
        Active dropdown item
      </a>
      <a href="#" class="dropdown-item">
        Other dropdown item
      </a>
      <hr class="dropdown-divider">
      <a href="#" class="dropdown-item">
        With a divider
      </a>
    </div>
  </div>
</div>

标签: javascripthtml

解决方案


在事件处理程序中closeDropdowns()切换类之前调用​​。is-active

function dropdowns() {
    var dropdowns = document.querySelectorAll('.dropdown:not(.is-hoverable)');

    if (dropdowns.length > 0) {
        dropdowns.forEach(function (el) {
            el.addEventListener('click', function (event) {
                event.stopPropagation();

                closeDropdowns(); // <== HERE
                el.classList.toggle('is-active');
            });
        });

        document.addEventListener('click', function (event) {
            closeDropdowns();
        });
    }

    function closeDropdowns() {
        dropdowns.forEach(function (el) {
            el.classList.remove('is-active');
        });
    }
}

但是,您应该添加一个检查以测试下拉列表当前是否打开,如果是,请跳过切换类,因为这将关闭并再次打开它。

el.addEventListener('click', function (event) {
    const isActive = el.classList.contains('is-active');

    closeDropdowns();

    if (!isActive) {
        el.classList.toggle('is-active'); // or simply el.classList.add('is-active');
    }
    
    event.stopPropagation();
});

推荐阅读