阻止某些事件侦听器触发事件​​但允许父侦听器触发

时间:2015-09-21 18:41:13

标签: javascript events ember.js

有没有办法阻止某个事件链中的某些侦听器触发某个事件但是允许其他链上的其他人触发?

例如我有这个结构

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

假设我有点击事件监听器附加到body,div#1和div#2。在div#2事件监听器中是否可以阻止事件将其转换为div#1或其间的任何其他侦听器并允许事件在body元素上触发?

我说这是因为我使用谷歌地图和emberjs来构建一堆可以在地图上显示的交互式信息框。问题是,ember将body事件监听器附加到body元素上,而google将它们附加到其他未知级别。当在谷歌地图覆盖内部托管的emberjs HTML节点触发点击事件时,事件必须首先通过谷歌地图处理程序才能到达余烬之前。

这导致了一些意想不到的副作用,比如谷歌地图以为我点击了其他标记。 IE浏览器。这个问题。 Mousing over Infobox fires hover event on markers that are behind it

1 个答案:

答案 0 :(得分:1)

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

另一种方法是,如果您没有自己添加事件侦听器但是您知道必须触发事件的节点,就像Ember和body元素一样,您可以停止传播事件您控制然后触发body上的点击事件的处理程序。这不是最优雅的解决方案,但考虑到所描述的情况,我不确定是否有另一种方式。您可以通过单击按钮C来查看此版本。

&#13;
&#13;
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();
});
&#13;
<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>
&#13;
&#13;
&#13;