Basically I have multiple parent div
with pairs of button
and div
child elements.
What I want to do is impose changes to the "related" div when a button is clicked. So if Button 2 is clicked, the changes should be imposed on toast 2. My issue is that no matter the button clicked it's only the first occurrence that is changed.
In my example I set the click to change the display
value of the relevant element as an example, but in reality any CSS change should be possible.
Here is a link to a complete and functional codepen as well.
function hide() {
var element = document.querySelector('.toast');
element.style.display = (element.style.display == 'none') ? 'block' : 'none';
}
.parent {
position : relative;
display : inline-block;
height : 55px;
}
button#button {
width : 100px;
height : 35px;
}
.toast {
display : block;
position : absolute;
top : 40px;
background-color : black;
}
<div >
<button id="button" onclick="hide()">Button 1</button>
<div >A box with text</div>
</div>
<div >
<button id="button" onclick="hide()">Button 2</button>
<div >A box with text</div>
</div>
<div >
<button id="button" onclick="hide()">Etc...</button>
<div >A box with text</div>
</div>
CodePudding user response:
- Don't duplicate IDs
- Avoid using
onclick
attributes. They have a number of drawbacks andaddEventListener
makes this easier. - Pay attention to the event object that is passed to your listener. It will tell you where the click was.
- Navigate up (using
closest
) and down (usingquerySelector
) the DOM from that element
function hide(event) {
// We're using event delegation so if the click isn't from a button we stop immediately
if (!event.target.matches(".parent button")) {
return false;
}
// Seach from the button up until we find the parent
const parent = event.target.closest(".parent");
// Search down from the parent until we find the toast
const toast = parent.querySelector('.toast');
toast.style.display = (toast.style.display == 'none') ? 'block' : 'none';
}
addEventListener('click', hide);
.parent {
position: relative;
display: inline-block;
height: 55px;
}
.parent button {
width: 100px;
height: 35px;
}
.toast {
display: block;
position: absolute;
top: 40px;
background-color: black;
}
<div >
<button>Button 1</button>
<div >A box with text</div>
</div>
<div >
<button>Button 2</button>
<div >A box with text</div>
</div>
<div >
<button>Etc...</button>
<div >A box with text</div>
</div>