在某个子元素之后停止事件传播

时间:2019-04-30 07:34:42

标签: javascript jquery

我不确定我是否正确提出了问题,我有以下代码。

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>

单击任何li项后,控制台将输出li,即使是第二个li项。

如何使用普通的JavasScript实现相同的目的?要将事件目标限制为li,而不是对任何孩子都没有限制?

我尝试过:

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

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

但是在点击第二个li项时,它会记录div

2 个答案:

答案 0 :(得分:6)

要使其在普通JS中起作用,您可以从closest()调用e.target来确定事件是由li引发还是由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>

请注意,IE本身不支持closest(),但是有polyfill available

答案 1 :(得分:2)

单击ul中的任何内容时,您可能只找到.closest <li>并记录下来:

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>