0

I would like to toggle the dropdown for the each of these boxes, but for some reason only the first one gets visible:

const button = document.querySelector("button");
const dropdown = document.querySelector(".dropdown");

button.addEventListener("click", () => {
  dropdown.classList.toggle("dropdown-visible");
})
.box {  
  height: 100px;
  width: 300px;
  position: relative;
}

.dropdown {
  height: 100px;
  width: 100%;
  position: absolute;
  background: red;
  top: 100%;
  right: 0;
  display: none;
}

.dropdown-visible {
  display: block;
}
<div class="box">
  box 1
  <button>toggle</button>
  <div class="dropdown">dropdown content</div>
</div>
<div class="box">
  box 2
  <button>toggle</button>
  <div class="dropdown">dropdown content</div>
</div>
<div class="box">
  box 3
  <button>toggle</button>
  <div class="dropdown">dropdown content</div>
</div>

I guess I should loop through these, but when I tried the querySelectorAll, it did not work..

Smithy
  • 807
  • 5
  • 17
  • 43
  • `document.querySelector(".dropdown")` is singular, so only selects one element – freedomn-m Feb 15 '21 at 14:54
  • 1
    Does this answer your question? [querySelector and querySelectorAll vs getElementsByClassName and getElementById in JavaScript](https://stackoverflow.com/questions/14377590/queryselector-and-queryselectorall-vs-getelementsbyclassname-and-getelementbyid) – freedomn-m Feb 15 '21 at 14:54
  • @freedomn-m yes :) Thanks everyone you are more than helpful, this community is a wonderful thing – Smithy Feb 15 '21 at 15:00

3 Answers3

2

On button click, navigate to the associated dropdown by using nextElementSibling of the clicked element:

for (const button of document.querySelectorAll('button')) {
  button.addEventListener('click', (e) => {
    button.nextElementSibling.classList.toggle("dropdown-visible");
  });
}
.box {  
  height: 100px;
  width: 300px;
  position: relative;
}

.dropdown {
  height: 100px;
  width: 100%;
  position: absolute;
  background: red;
  top: 100%;
  right: 0;
  display: none;
}

.dropdown-visible {
  display: block;
}
<div class="box">
  box 1
  <button>toggle</button>
  <div class="dropdown">dropdown content</div>
</div>
<div class="box">
  box 2
  <button>toggle</button>
  <div class="dropdown">dropdown content</div>
</div>
<div class="box">
  box 3
  <button>toggle</button>
  <div class="dropdown">dropdown content</div>
</div>
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
1

Delegation

document.getElementById("container").addEventListener("click", e => {
  const tgt = e.target;
  if (tgt.tagName==="BUTTON") {
    tgt.nextElementSibling.classList.toggle("dropdown-visible");
  }
})
.box {  
  height: 100px;
  width: 300px;
  position: relative;
}

.dropdown {
  height: 100px;
  width: 100%;
  position: absolute;
  background: red;
  top: 100%;
  right: 0;
  display: none;
}

.dropdown-visible {
  display: block;
}
<div id="container">
<div class="box">
  box 1
  <button>toggle</button>
  <div class="dropdown">dropdown content</div>
</div>
<div class="box">
  box 2
  <button>toggle</button>
  <div class="dropdown">dropdown content</div>
</div>
<div class="box">
  box 3
  <button>toggle</button>
  <div class="dropdown">dropdown content</div>
</div>
</div>

One button loops

const button = document.querySelector("button");// only one button
const dropdowns = document.querySelectorAll(".dropdown");

button.addEventListener("click", () => {
  dropdowns.forEach(dropdown => dropdown.classList.toggle("dropdown-visible"));
})
.box {
  height: 100px;
  width: 300px;
  position: relative;
}

.dropdown {
  height: 100px;
  width: 100%;
  position: absolute;
  background: red;
  top: 100%;
  right: 0;
  display: none;
}

.dropdown-visible {
  display: block;
}
<button>toggle</button>
<div class="box">
  box 1
  <div class="dropdown">dropdown content</div>
</div>
<div class="box">
  box 2

  <div class="dropdown">dropdown content</div>
</div>
<div class="box">
  box 3

  <div class="dropdown">dropdown content</div>
</div>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
1

This should help!

const buttons = document.querySelectorAll("button");
const dropdowns = document.querySelectorAll(".dropdown");

buttons.forEach((btn, index) => {
  btn.addEventListener("click", () => {
    dropdowns[index].classList.toggle("dropdown-visible");
  })
})
.box {
  height: 100px;
  width: 300px;
  position: relative;
}

.dropdown {
  height: 100px;
  width: 100%;
  position: absolute;
  background: red;
  top: 100%;
  right: 0;
  display: none;
}

.dropdown-visible {
  display: block;
}
<div class="box">
  box 1
  <button>toggle</button>
  <div class="dropdown">dropdown content</div>
</div>
<div class="box">
  box 2
  <button>toggle</button>
  <div class="dropdown">dropdown content</div>
</div>
<div class="box">
  box 3
  <button>toggle</button>
  <div class="dropdown">dropdown content</div>
</div>
Som Shekhar Mukherjee
  • 4,701
  • 1
  • 12
  • 28