Пытаясь решить эту проблему для себя, я заметил, что на самом деле можно сохранить прокрутку страницы и фокус ввода, отключив изменения чисел, попытавшись повторно запустить перехваченное событие в родительском элементе * 1001.* на котором он был пойман, просто так:
e.target.parentElement.dispatchEvent(e);
Однако, это вызывает ошибку в консоли браузера и, вероятно, не гарантируется, что она будет работать везде (я тестировал только на Firefox), поскольку она намеренноневерный код.
Другое решение, которое хорошо работает, по крайней мере, в Firefox и Chromium, - временно создать элемент <input>
readOnly
, например:
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); });
Один побочный эффект, который яВы заметили, что это может привести к мерцанию поля на долю секунды, если у вас другой стиль для полей readOnly
, но, по крайней мере, для моего случая это не проблема.
Точно так же (как объяснено в ответе Джеймса) вместо изменения свойства readOnly
вы можете blur()
поле и затем focus()
его обратно, но again, в зависимости от используемых стилей, может возникнуть некоторое мерцание.
В качестве альтернативы, как уже упоминалось в других комментариях, вы можете просто вызвать preventDefault()
для события.Предполагая, что вы обрабатываете только события wheel
на числовых входах, которые находятся в фокусе и под курсором мыши (вот что означают три вышеуказанных условия), отрицательное влияние на взаимодействие с пользователем будет практически нулевым.