Пытаясь решить эту проблему для себя, я заметил, что на самом деле можно сохранить прокрутку страницы и фокус ввода при отключении изменения числа, попытавшись повторно запустить событие catch на родительском элементе того, <input type="number"/>
на котором оно было поймано. , просто так:
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()
вернуть его обратно, но опять же, в зависимости от используемых стилей, может возникнуть некоторое мерцание.
В качестве альтернативы, как упоминалось в других комментариях здесь, вы можете просто позвонить preventDefault()
на мероприятие. Предполагая, что вы обрабатываете wheel
события только для числовых входов, которые находятся в фокусе и под курсором мыши (это то, что означают три вышеуказанных условия), негативное влияние на взаимодействие с пользователем будет практически нулевым.