阻止某些事件侦听器触发某个事件,但允许父侦听器触发 [英] Prevent certain event listeners from firing for an event but allow the parent listeners to fire

查看:91
本文介绍了阻止某些事件侦听器触发某个事件,但允许父侦听器触发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有什么方法可以防止某个事件链中的某些侦听器触发某个事件,但允许其他更远的链触发该事件?

Is there any way to prevent some of the listeners in an event's chain from firing for an event but allow others farther up the chain to fire?

例如,我具有这种结构

<body>
    <div id="1">
       <div id="2">
          <button>Click Me</button>
       </div>
    </div>
</body> 

我说我有单击事件侦听器附加到body,div#1和div#2。 div#2事件侦听器是否有可能阻止该事件进入div#1或介于两者之间的任何其他侦听器,并允许该事件在body元素上触发?

Lets say i have click event listeners attached to body, div#1, and div#2. Would it be possible at div#2 event listener to prevent the event making it to div#1 or any other listeners in between and allow the event to fire on the body element?

我之所以这样说是因为我正在使用Google地图和emberjs构建一堆可以在地图上显示的交互式信息框。问题在于ember在body元素上附加了事件侦听器,而google在其他未知级别附加了它们。当emberjs触发click事件时,托管在google地图叠加层中的HTML节点必须先通过google地图处理程序,然后该事件才到达ember。

I say this because i am using google maps and emberjs to build a bunch of interactive infoboxes that can be shown on a map. The problem is that ember attaches event listeners on the body element and google attaches them at some other unknown level. When a click event is fired by emberjs HTML nodes hosted inside a google maps overlay the event must first pass through google maps handlers before it reaches ember's.

这会引起一些意外的副作用,例如Google Maps认为我正在点击其他标记。 IE浏览器这个问题。 将鼠标悬停在Infobox上会在标记上触发悬停事件

This is causing some unintended side effects like google maps thinking i'm clicking on other markers. IE. this issue. Mousing over Infobox fires hover event on markers that are behind it

推荐答案

您可以根据点击目标是有条件地执行处理程序代码。在此示例中,您可以看到单击按钮A时,事件触发按钮b和div 1,但不触发div2。如果单击按钮B,则事件触发所有三个按钮。

You could conditionally execute your handler code based on what the click target was. In this example, you can see that when button A is clicked, the event fires for button b and div 1, but not div 2. If button B is clicked, the event fires for all three.

另一种方法,如果您不是自己添加事件侦听器,但您知道必须在哪个节点上触发事件,例如Ember和 body 元素,可以停止在您控制的处理程序中传播事件,然后在 body 上触发click事件。这不是最优雅的解决方案,但是鉴于上述情况,我不确定是否还有其他方法。您可以通过单击按钮C来查看此版本。

Another approach, if you are not adding the event listeners yourself but you know on which node you must trigger the event, as in the case of Ember and the body element, you could stop propagation of the event in a handler that you do control and then trigger the click event on body. This isn't the most elegant solution, but given the situation as described I'm not sure if there's another way. You can see this version by clicking button C.

function log(s) {
  var e = document.createElement('div');
  e.innerHTML = s;
  document.body.appendChild(e);
}

document.getElementById('1').addEventListener('click', function (e) { log('Div 1 clicked'); });
document.getElementById('2').addEventListener('click', function (e) {
  if (event.target.id !== "a") {
      log('Div 2 clicked');
  }
});
document.getElementById('a').addEventListener('click', function (e) { log('Button A clicked'); });
document.getElementById('b').addEventListener('click', function (e) { log('Button B clicked'); });

document.body.addEventListener('click', function (e) { log('Ember click event fired'); });
document.getElementById('c').addEventListener('click', function (e) {
  log('Button C clicked');
  e.stopPropagation();
  document.body.click();
});

<div id="1">
  <div id="2">
    <button id="a">Button A</button>
    <button id="b">Button B</button>
    <button id="c">Button C</button>
  </div>
</div>

这篇关于阻止某些事件侦听器触发某个事件,但允许父侦听器触发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆