问题
I have a listener attached to resize event on window
object. Deeper in my code, I have some input
fields.
To avoid some issues on android devices, I’d like to prevent resize listeners from being fired when an input field is focused (android device resize browser window when opening keyboard, unlike IOS).
main.js
window.addEventListener(‘resize’, () => {
// Some stuff here
});
someFile.js
field.addEventListener(‘input’, () => {
// Here I want to disable the resize event only once
});
I came accross the following solutions, without any success so far :
removeEventListener()
Not suitable at all, since I need to specify a reference to the listener function. Not only do I have to remove listeners one by one, I also have to list them all, and rebind them after.
event.stopPropagation()
someFile.js
field.addEventListener(‘focusin’, () => {
window.addEventListener(‘resize’, event => {
event.stopPropagation();
// also tried event.stopImmediatePropagation()
});
});
But since listeners are called in declared order, it doesn’t prevent anything (it is declared last). Plus I have to rebind everything again on focusout
.
What I want
I’m aware of some tricks using global variables that can achieve what I want, but they are kinda ugly, not to mention I try to avoid global variables as much as I can.
Is there any elegant way, to invoke an early stopPropagation()
like function on all resize listeners, and prevent them from firing from deep function inside code ?
Or is there a better architecture, for example a global function that can trigger when any input element on the page gets focus, and prevent the resize event regardless of the focused element ?
回答1:
I'd add a resize
listener unconditionally, and inside it, check if document.activeElement
is one of the fields:
window.addEventListener(
'resize',
(e) => {
if (document.activeElement && document.activeElement.matches('input')) {
console.log('propagation stopped');
e.stopPropagation();
} else {
console.log('propagation not stopped');
}
},
true // enable useCapture here with this third argument
// to stop propagation as early as possible
);
<input>
Change the selector string passed to matches
to match your needs. The above snippet uses input
, which will match any input field. If you only want to stop propagation when the focused input has a class of foo
, you'd use
.matches('input.foo')
To match multiple selectors, separate them with a comma, eg
.matches('input, textarea')
will match both an input and a textarea.
Also keep in mind that Javascript syntax requires straight quotes, not so-called smart quotes, which will cause syntax errors.
来源:https://stackoverflow.com/questions/57142999/stop-propagation-of-a-specific-event-inside-another-event-listener