Prevent certain event listeners from firing for an event but allow the parent listeners to fire

一世执手 提交于 2020-01-04 05:13:07

问题


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?

For instance i have this structure

<body>
    <div id="1">
       <div id="2">
          <button>Click Me</button>
       </div>
    </div>
</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?

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.

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


回答1:


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.

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>


来源:https://stackoverflow.com/questions/32702399/prevent-certain-event-listeners-from-firing-for-an-event-but-allow-the-parent-li

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!