I'm doing a small application just to learn ES6 stuff and I've found a problem with addEventListener
and parent/child events.
I have a menu consisting on several divs that have an image (an avatar) and some text. Each div has an data-id attribute to get the clicked elements id and I have put an addEventListener
on each row:
<div class="row" data-id="1">
<img src="avatar" />
Lorem ipsum
</div>
...
And the js:
const rows = document.querySelectorAll('.row');
rows.forEach(row => row.addEventListener('click',selectRow));
function selectRow(e){
var row = e.target;
alert(row.dataset.id);
}
The problem comes when I click on the avatar. It fires the click event, but the target is the img element, not the div, so I can't get the data-id attribute.
I have tried many approaches (like this one) but it prevents firing the event when clicking on the avatar, so not on a solution as the avatar is part of the row and it may get clicked :S
I have set a jsfiddle to show my problem. Any help would be appreciated :)
https://jsfiddle.net/igorosabel/o64b404y/1/
To only trigger parent click event when a child is clicked with JavaScript, we call stopPropagation . parent. addEventListener( "click", (e) => { e. stopPropagation(); console.
Attach the event listener to the parent element getElementById('buttons') . addEventListener('click', handler) attaches the event listener to the parent element of buttons. This listener reacts to buttons clicks because the button click event bubbles through ancestors (thanks to the event propagation).
It fires the click event, but the target is the img element, not the div, so I can't get the data-id attribute.
Correct. target
is the actual target of the event, regardless which element you hooked the event on, which may be different from the actual target because of bubbling (in your case, click bubbles from the img
to the div
).
You can get the element you hooked the event on via this
(provided you let the event system set this
for the handler) or e.currentTarget
.
Your fiddle as a snippet with that change:
const rows = document.querySelectorAll('.row');
rows.forEach(row => row.addEventListener('click',showId));
function showId(e){
console.log("Using this:", this.dataset.id);
console.log("Using e.currentTarget:", e.currentTarget.dataset.id);
}
.row{
border: 1px solid #000;
margin-bottom: 10px;
padding: 10px;
}
<div class="row" data-id="1">
<img src="https://placehold.it/100x100" />
Lorem ipsum
</div>
<div class="row" data-id="2">
<img src="https://placehold.it/100x100" />
Lorem ipsum
</div>
<div class="row" data-id="3">
<img src="https://placehold.it/100x100" />
Lorem ipsum
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With