Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 257
Siddharth Thevaril Avatar asked Jan 26 '23 09:01

Siddharth Thevaril


2 Answers

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.

like image 139
Rory McCrossan Avatar answered Jan 29 '23 14:01

Rory McCrossan


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>
like image 29
CertainPerformance Avatar answered Jan 29 '23 12:01

CertainPerformance