I have multiple divs on the page with the class 'item' – I'd like to include a button within the div that when clicked will toggle append/remove the class 'zoom' on the 'item' div…
<div >
<button ></button>
</div>
I've found plenty of code examples that target an id element, but struggling to find a solution that works with multiples of the same class element on one page.
Many thanks in advance!
CodePudding user response:
You can use querySelectorAll
to get all of the buttons
and then you can use forEach
so you can target the element's item
parent.
// Get all the buttons
let zoomer_button = document.querySelectorAll('.zoomer');
// Loop through the buttons.
// Arrow function allows to pass the element
zoomer_button.forEach(button => {
// Add an event listener for a click on the button.
button.addEventListener('click', function(e) {
// the e is the event, and then you check what the target is, which is the button.
// then you can toggle a 'zoom' class on the parent 'item'
e.target.parentNode.classList.toggle('zoom');
});
});
.item.zoom {
background-color: blue;
}
<div >
<button >button</button>
</div>
<div >
<button >button</button>
</div>
<div >
<button >button</button>
</div>
<div >
<button >button</button>
</div>
<div >
<button >button</button>
</div>
If it's nested a layer deeper, you can use parentNode
twice.
// Get all the buttons
let zoomer_button = document.querySelectorAll('.zoomer');
// Loop through the buttons.
// Arrow function allows to pass the element
zoomer_button.forEach(button => {
// Add an event listener for a click on the button.
button.addEventListener('click', function(e) {
// the e is the event, and then you check what the target is, which is the button.
// then you can toggle a 'zoom' class on the parent 'item'
e.target.parentNode.parentNode.classList.toggle('zoom');
});
});
.item.zoom {
background-color: blue;
}
<div >
<div >
<button >button</button>
</div>
</div>
<div >
<div >
<button >button</button>
</div>
</div>
<div >
<div >
<button >button</button>
</div>
</div>
<div >
<div >
<button >button</button>
</div>
</div>
CodePudding user response:
You can use querySelectorAll and access each element with e.target
document.querySelectorAll('.item > .zoomer')
.forEach(elem => elem.addEventListener('click', e => {
e.target.classList.toggle('someClass')
}))
.someClass{
background:limegreen;
}
<div >
<button >1</button>
</div>
<div >
<button >2</button>
</div>
<div >
<button >3</button>
</div>
<div >
<button >4</button>
</div>
CodePudding user response:
In the example below, are 7 <button>
s that do various stuff -- details are commented in example.
// Render 7 <menu>/<button> combos
[...new Array(7)].forEach((item, index) => {
document.querySelector('main').insertAdjacentHTML('beforeend', `
<menu >
<button >${index}</button>
</menu>`);
});
/*~~~~~~~~~~~~~~~~~~~~~~~.btn0*/
// Click <button> remove it's parent (which also removes the <button>)
document.querySelector('.btn0').onclick = function(e) {
this.parentElement.remove();
}
/*~~~~~~~~~~~~~~~~~~~~~~~.btn1*/
// Click <button> -- <button> is removed but it's contents is left behind
document.querySelector('.btn1').onclick = unWrap;
function unWrap(e) {
const clicked = e.target;
const parent = clicked.parentElement;
while (clicked.firstChild) {
parent.insertBefore(clicked.firstChild, clicked);
}
clicked.remove();
}
/*~~~~~~~~~~~~~~~~~~~~~.btn4-6*/
// Collect all tags with a class that starts with "btn"
const btns = document.querySelectorAll("[class^='btn']");
// Adding .target class to the last 2 <button>s
btns.forEach((btn, idx) => {
if (idx > 4) btn.classList.add('target')
});
/*~~~~~~~~~~~~~~~~~~~~~~~.btn2*/
// Target third <button> by index
/*
When <button> clicked, it's parent gets .hide class which is:
visibility:hidden which would normally hide the <button> as well, but
.btn2 has visibility explicitly set to visible
*/
btns[2].onclick = e => e.target.closest('menu').classList.toggle('hide');
/*~~~~~~~~~~~~~~~~~~~~~~~.btn3*/
/*
Everytime the <button> is clicked, a copy of itself is made and the
clones also have this ability as well
*/
btns[3].addEventListener('click', copySelf);
function copySelf(e) {
let dupe = e.target.cloneNode(true);
e.target.parentElement.append(dupe);
dupe.onclick = copySelf;
}
/*~~~~~~~~~~~~~~~~~~~~~.btn4-6*/
/*
The click event is bound to the parent/ancestor tag <section>
Any click to any <button> will trigger the event handler.
.btn4, .btn5, and .btn6 all react in a specific manner because
the event handler, delegateClick(e) is using flow control statements and
specific criteria.
*/
document.querySelector('main').onclick = delegateClick;
let armed = false;
function delegateClick(e) {
const clicked = e.target;
if (clicked.matches('button') && !armed) {
clicked.classList.add('armed');
armed = true;
return;
}
if (clicked.matches('.armed.target') && armed) {
clicked.parentElement.style.cssText = `font-size: 5rem; margin: 0`
clicked.replaceWith(`