Mientras trataba de resolver esto por mí mismo, noté que en realidad es posible retener el desplazamiento de la página y el enfoque de la entrada mientras deshabilita los cambios de número al intentar volver a disparar el evento capturado en el elemento principal del elemento <input type="number"/>
en el que se capturó , simplemente así:
e.target.parentElement.dispatchEvent(e);
Sin embargo, esto causa un error en la consola del navegador, y probablemente no se garantiza que funcione en todas partes (solo probé en Firefox), ya que es un código intencionalmente inválido.
Otra solución que funciona bien al menos en Firefox y Chromium es crear temporalmente el <input>
elemento readOnly
, así:
function handleScroll(e) {
if (e.target.tagName.toLowerCase() === 'input'
&& (e.target.type === 'number')
&& (e.target === document.activeElement)
&& !e.target.readOnly
) {
e.target.readOnly = true;
setTimeout(function(el){ el.readOnly = false; }, 0, e.target);
}
}
document.addEventListener('wheel', function(e){ handleScroll(e); });
Un efecto secundario que he notado es que puede hacer que el campo parpadee durante una fracción de segundo si tiene un estilo diferente para los readOnly
campos, pero al menos en mi caso, esto no parece ser un problema.
De manera similar, (como se explica en la respuesta de James) en lugar de modificar la readOnly
propiedad, puede cambiar blur()
el campo y luego focus()
regresar, pero nuevamente, dependiendo de los estilos en uso, puede ocurrir algo de parpadeo.
Alternativamente, como se mencionó en otros comentarios aquí, puede simplemente convocar preventDefault()
el evento. Suponiendo que solo maneja wheel
eventos en entradas numéricas que están enfocadas y bajo el cursor del mouse (eso es lo que significan las tres condiciones anteriores), el impacto negativo en la experiencia del usuario sería casi nulo.