Reputation: 847
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..
Upvotes: 0
Views: 293
Reputation: 8158
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>
Upvotes: 1
Reputation: 177692
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>
Upvotes: 1
Reputation: 370639
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>
Upvotes: 2