防止通过父元素处理程序触发处理程序

Prevent handler firing through parent element handler

本文关键字:处理 程序 元素      更新时间:2023-09-26

我想防止UL事件触发。我想这可以在它的父容器中使用stopImmediatePropagation来完成吗?

html

<div>
  <ul>
    <li>click me</li>
    <li>click me</li>
    <li>click me</li>
    <li>click me</li>
    <li>click me</li>
  </ul>
</div>

javascript

$('body').on('click', 'div', function(e) {
  e.stopImmediatePropagation();
  $('div').css('background', 'black');
});
$('body').on('click', 'ul', function() {
  $('ul').css('background', 'yellow');
});

http://jsbin.com/yositusega/edit?html,css,js,output-如果您单击UL,我希望它触发div事件,而不是UL。所以在这个例子中,UL背景不应该改变颜色,但是父DIV应该改变。所以黑色>深红色。

这可以通过DIV事件处理程序实现吗?如果可能的话,希望不必编辑UL事件。

说明

  • 将事件侦听器放置在父对象上(即ul
  • 在事件处理程序(eventSignal())中,通过确定event.targetCurrent(即ul)来确定event.target
  • 在事件处理程序结束时使用event.stopPropagation()

参考文献

  • MDN事件阶段*
  • W3学校活动阶段
  • 多个事件监听器

*在文章的最后,有一个演示可能有助于

代码段

我刚刚添加了一个额外的实用函数evPhase()。我不确定它是否正常工作,但它不会妨碍主功能eventSignal()。在观察了相位之后,我相信evPhase()是准确的,但没有足够的细节来告诉你BUBBLING_PHASE从未达到<ul>,因为event.stopPropagation()。。。如果用它代替event.stopImmediatePropagation(),则eventPhase可能是NONE。。否则它会扼杀整个过程,因为event.target不是event.currentTarget。。。。

无论如何,如果单击<li>周围的空间,则单击的是<ul>,而不是<li>。注意eventPhase是:

AT_TARGET - The event flow is in target phase, i.e. it is being evaluated at the event target

因此,看起来event.stopPropagation()正在停止BUBBLING_PHASE,因为如果事件冒泡到<ul>足够远,则evPhase()不会报告AT_TARGET

var ul = document.querySelector('ul');
ul.addEventListener('click', function(event) {
  eventSignal(event);
  evPhase(event);
}, false);
function eventSignal(event) {
  evPhase(event);
  if (event.target !== event.currentTarget) {
    var tgt = event.target;
    tgt.classList.toggle('on');
    tgt.classList.toggle('off');
  }
  event.stopPropagation();
  evPhase(event);
}
function evPhase(event) {
  var display = document.querySelector('output');
  var phase = event.eventPhase;
  switch (phase) {
    case 0:
      display.innerHTML += 'NONE<br/>';
      break;
    case 1:
      display.innerHTML += 'CAPTURING_PHASE - The event flow is in capturing phase<br/>';
      break;
    case 2:
      display.innerHTML += 'AT_TARGET - The event flow is in target phase, i.e. it is being evaluated at the event target<br/>';
      break;
    case 3:
      display.innerHTML += 'BUBBLING_PHASE - The event flow is in bubbling phase<br/>';
      break;
    default:
      return false;
  }
}
li {
  list-style: none;
  width: 24px;
  height: 24px;
  border: 3px outset grey;
  border-radius: 50px;
  cursor: pointer;
  text-align: center;
  font-size: 21px;
}
.on {
  background: yellow;
  color: blue;
  border-color: blue;
}
.off {
  background: #fd8;
}
<div>
  <ul>
    <li class="off">1</li>
    <li class="off">2</li>
    <li class="off">3</li>
    <li class="off">5</li>
    <li class="off">6</li>
  </ul>
</div>
<output></output>
<script src="http://gh-canon.github.io/stack-snippet-console/console.min.js"></script>