带For循环的下拉菜单:如何实现点击时自动关闭其他下拉菜单

问题描述 投票:0回答:1

我的菜单无法按我想要的方式工作。我通常只能用 for 循环编写菜单,但它不能像应有的那样工作。如果单击菜单项,它将保持打开状态,直到我再次单击它。我可以编写的菜单在单击它时显示内容,但当我单击菜单中的另一个项目时,其他下拉菜单不会自动关闭。如何更改代码来解决问题并在每次单击下一个菜单项时自动关闭其他下拉菜单?

const menu = document.getElementsByClassName('menu');
const menucontent = document.getElementsByClassName('item');
const subTitle = document.getElementsByClassName('sub-title');
const subItem = document.getElementsByClassName('sub-item');
for (let i = 0; i < menu.length; i++) {
  menu[i].addEventListener('click', () => {
    menucontent[i].classList.toggle('show');
    menu[i].classList.toggle('darkgrey');
  });

  window.addEventListener('click', function(e) {
    if (!e.target.matches('.menu') && !e.target.matches('.item') && !e.target.matches('.sub-title') && !e.target.matches('.fas')) {
      menu[i].classList.remove('darkgrey');
      menucontent[i].classList.remove('show');
    } else if (e.target.matches('.sub-title') || e.target.matches('.fas')) {
      subItem[0].classList.toggle('present');
      subTitle[0].classList.toggle('clear');
      menu[0].classList.toggle('darkgrey');
      menucontent[0].classList.toggle('show');
    }
  })
}

我尝试使用 forEach 循环、querySelector 和 querySelectorAll 选项,但现在失败了。

javascript for-loop foreach
1个回答
2
投票

未测试 (因为未提供 HTML)

我修改了您的代码以跟踪当前打开的下拉列表,并在单击新菜单项时将其关闭。查看修改后的代码并阅读评论以了解我如何解决您的问题。我希望它对你有用。

const menuItems = document.querySelectorAll('.menu');
const menuContents = document.querySelectorAll('.item');
const subTitles = document.querySelectorAll('.sub-title');
const subItems = document.querySelectorAll('.sub-item');

let currentlyOpenMenu = null;

menuItems.forEach((menuItem, index) => {
  menuItem.addEventListener('click', (e) => {
    e.stopPropagation(); // Prevents the click event from propagating to the window
    if (currentlyOpenMenu !== null && currentlyOpenMenu !== index) {
      // Close the currently open menu
      menuContents[currentlyOpenMenu].classList.remove('show');
      menuItems[currentlyOpenMenu].classList.remove('darkgrey');
    }
    
    // Toggle the clicked menu
    menuContents[index].classList.toggle('show');
    menuItem.classList.toggle('darkgrey');

    // Update the currently open menu
    currentlyOpenMenu = (currentlyOpenMenu === index) ? null : index;
  });
});

window.addEventListener('click', function(e) {
  if (!e.target.matches('.menu') && !e.target.matches('.item') && !e.target.matches('.sub-title') && !e.target.matches('.fas')) {
    // Close the currently open menu when clicking outside any menu
    if (currentlyOpenMenu !== null) {
      menuContents[currentlyOpenMenu].classList.remove('show');
      menuItems[currentlyOpenMenu].classList.remove('darkgrey');
      currentlyOpenMenu = null;
    }
  } else if (e.target.matches('.sub-title') || e.target.matches('.fas')) {
    // Handle sub-title and fas clicks if needed
    subItems[0].classList.toggle('present');
    subTitles[0].classList.toggle('clear');
    menuItems[0].classList.toggle('darkgrey');
    menuContents[0].classList.toggle('show');
  }
});

© www.soinside.com 2019 - 2024. All rights reserved.