Mentre cercavo di risolverlo da solo, ho notato che in realtà è possibile mantenere lo scorrimento della pagina e il focus dell'input disabilitando le modifiche del numero tentando di riattivare l'evento catturato sull'elemento genitore del <input type="number"/>
su cui era stato catturato , semplicemente così:
e.target.parentElement.dispatchEvent(e);
Tuttavia, questo causa un errore nella console del browser e probabilmente non è garantito che funzioni ovunque (ho provato solo su Firefox), poiché si tratta di codice intenzionalmente non valido.
Un'altra soluzione che funziona bene almeno su Firefox e Chromium è quella di creare temporaneamente l' <input>
elemento readOnly
, in questo modo:
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 effetto collaterale che ho notato è che può causare uno sfarfallio del campo per una frazione di secondo se hai uno stile diverso per readOnly
campi, ma almeno per il mio caso, questo non sembra essere un problema.
Allo stesso modo, (come spiegato nella risposta di James) invece di modificare la readOnly
proprietà, puoi blur()
il campo e poifocus()
nuovo, ma ancora una volta, a seconda degli stili in uso, potrebbe verificarsi uno sfarfallio.
In alternativa, come menzionato in altri commenti qui, puoi semplicemente chiamare preventDefault()
l'evento. Supponendo che gestisci solo wheel
eventi sugli input numerici che sono a fuoco e sotto il cursore del mouse (questo è ciò che significano le tre condizioni sopra), l'impatto negativo sull'esperienza utente sarebbe quasi nullo.