Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

addEventListener event on parent target child

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/

like image 491
Iñigo Gorosabel Avatar asked Mar 07 '17 09:03

Iñigo Gorosabel


People also ask

How do you only trigger parent click event when a child is clicked?

To only trigger parent click event when a child is clicked with JavaScript, we call stopPropagation . parent. addEventListener( "click", (e) => { e. stopPropagation(); console.

How can parent add event listener?

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).


1 Answers

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>
like image 136
T.J. Crowder Avatar answered Oct 24 '22 14:10

T.J. Crowder