javascript 如何向多个重复div添加EventListener

xmjla07d  于 2023-01-11  发布在  Java
关注(0)|答案(2)|浏览(142)

我正在制作某种汉堡菜单,一个页面可能有多个汉堡菜单,所以如果我点击任何一个div,它应该会为我打开菜单。
例如,在同一页面中,如果我点击按钮一,它应该为我打开菜单,如果我可以点击按钮二,它应该为我打开菜单,等等...
到目前为止,我尝试了这个,它只为第一个div工作,其余的div不工作,任何帮助吗?

var kebab = document.querySelectorAll('.kebab'),
            dropdown = document.querySelector('.dropdown');

        kebab.forEach(element => {
            element.addEventListener('click', function() {
                dropdown.classList.toggle('hidden');
                dropdown.classList.remove('block');
            })
        })

我的html代码

所以每个父div都有.kebab,如果我点击.kebab div,它应该会打开.dropdown div,以此类推...

<div class="1">
<div class="kebab">
<div class="dropdown hidden">
<div class="kebabmenu ">
 <a href="">Preview Invoice</a>
<a href="">Download Invoice</a>
</div>
</div>
</div>
</div>

<div class="1">
<div class="kebab">
<div class="dropdown hidden">
<div class="kebabmenu ">
 <a href="">Preview Invoice</a>
<a href="">Download Invoice</a>
</div>
</div>
</div>
</div>
iqxoj9l9

iqxoj9l91#

就像@ppower提到的,你把所有的汉堡菜单指向一个下拉菜单,在你的嵌套结构中,你可以像这样重写代码:

var kebab = document.querySelectorAll(".kebab");

kebab.forEach((element) => {
  element.addEventListener("click", function () {
    var dropdown = element.querySelector(".dropdown");

    dropdown.classList.toggle("hidden");
    dropdown.classList.remove("block");
  });
});

它会在那个特定的.kebab中找到一个下拉菜单并切换它。希望这能有所帮助。codesandbox demo

==更新===

回答您关于如何在单击外部时关闭下拉菜单的问题-我会在页面上使用一个通用的单击侦听器,并计算其目标或父对象是否是汉堡菜单

document.addEventListener("click", handleDocumentClick);

function handleDocumentClick(event) {
  const clickedElement = event.target;
  const isKebabClick = clickedElement.matches(".kebab");
  if (isKebabClick) {
    const dropdown = clickedElement.querySelector(".dropdown");
    dropdown.classList.toggle("hidden");
    return;
  }

  // close all dropdowns if the click happens outside kebab
  if (!clickedElement.closest(".kebab")) {
    const allDropdowns = document.querySelectorAll(".dropdown");
    allDropdowns.forEach((dropdown) => {
      dropdown.classList.add("hidden");
    });
  }
}
2vuwiymt

2vuwiymt2#

这个片段也许能说明这一点。

var kebab = document.querySelectorAll('.kebab');

kebab.forEach(element => {
  element.addEventListener('click', function(evt) {
    evt.currentTarget.firstElementChild.classList.toggle('hidden');

  })
})
.hidden {
  display: none;
}

.kebab {
  width: 200px;
  height: 50px;
  background-color: rgb(200, 200, 200);
  margin: 50px;
  padding: 10px;
}

.kebab>.dropdown {
  border: 1px solid black;
}
<div class="1">
  <div class="kebab">
    <div class="dropdown">
      <div class="kebabmenu ">
        <a href="">Preview Invoice</a>
        <a href="">Download Invoice</a>
      </div>
    </div>
  </div>
</div>

<div class="1">
  <div class="kebab">
    <div class="dropdown">
      <div class="kebabmenu ">
        <a href="">Preview Invoice</a>
        <a href="">Download Invoice</a>
      </div>
    </div>
  </div>
</div>

另外,虽然你没有问这个问题,但你不需要在每个菜单按钮上都有一个监听器。这个代码片段说明了一种减少监听器数量的方法。一开始可能看起来有点奇怪,但当你开始有很多带有监听器的活动元素时,这种方法会很有帮助。这个answer对我以前的一个问题可能会提供更好的解释。
一个一个三个一个一个一个一个一个四个一个一个一个一个一个五个一个

相关问题