问题
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