Siddharth Thevaril
Siddharth Thevaril

Reputation: 3798

Stop event propagation after a certain child element

I'm unsure if I framed the question correctly, I have the following code.

var ul = $( '#root' );

ul.on( 'click', 'li', function( e ) {
  console.log( e.currentTarget )
});
* {
  border: 1px solid;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="root">
  <ul>
    <li></li>
    <li><div>Some Text</div></li>
    <li></li>
  </ul>
</div>

Upon clicking any of the li items, the console outputs li, even for the 2nd li item.

How can I use plain JavasScript to achieve the same? Tolimit the event target to li and not go beyond that to any of the children?

I tried this:

var root = document.getElementById( 'root' );

root.addEventListener( 'click', function( e ) {
  console.log( e.target )
}); 

But upon clicking the 2nd li item, it logs div

Upvotes: 4

Views: 59

Answers (2)

Rory McCrossan
Rory McCrossan

Reputation: 337700

To make this work in plain JS you can call closest() from the e.target to determine if the event was raised by an li, or the child of an li:

var li = document.getElementById('root');

root.addEventListener('click', function(e) {      
  var li = e.target.closest('li');
  if (li)
    console.log(li.tagName); // a little redundant, but purely for demo purposes
});
* {
  border: 1px solid;
}
<div id="root">
  <ul>
    <li></li>
    <li>
      <div>Some Text</div>
    </li>
    <li></li>
  </ul>
</div>

Note that closest() is not natively supported in IE, but there is a polyfill available.

Upvotes: 6

CertainPerformance
CertainPerformance

Reputation: 371138

When anything inside the ul is clicked, you might just find the .closest <li>, and log it:

var root = document.getElementById('root');

root.addEventListener('click', function(e) {
  const possibleLi = e.target.closest('li');
  if (!possibleLi) {
    return;
  }
  console.log(possibleLi);
});
* {
  border: 1px solid;
}
<div id="root">
  <ul>clicking here should do nothing
    <li></li>
    <li>
      <div>Some Text</div>
    </li>
    <li></li>
  </ul>
</div>

Upvotes: 2

Related Questions