Disable scrolling to `<input type = number>`
Is it possible to disable the scroll wheel that changes the number in the input number field? I messed up with webkit specific CSS to remove the counter, but I would like to completely get rid of this behavior. I like to use type=number , since it calls a good keyboard on iOS.
Prevent the default behavior for the mousewheel event on input number elements, as others have suggested (calling "blur ()" is usually not the preferred way to do this because it will not be what the user wants).
BUT. I would avoid listening to the mousewheel event on all elements of the input number all the time and would do it only when the element is in focus (that is, when the problem exists). Otherwise, the user will not be able to scroll the page when the mouse pointer is somewhere above the input number element.
Solution for jQuery:
// disable mousewheel on a input number field when in focus // (to prevent Cromium browsers change the value when scrolling) $('form').on('focus', 'input[type=number]', function (e) { $(this).on('wheel.disableScroll', function (e) { e.preventDefault() }) }) $('form').on('blur', 'input[type=number]', function (e) { $(this).off('wheel.disableScroll') }) (delegate focus events to the surrounding form element - to avoid many event listeners that degrade performance.)
$(document).on("wheel", "input[type=number]", function (e) { $(this).blur(); }); input = document.getElementById("the_number_input") input.addEventListener("mousewheel", function(event){ this.blur() }) For a jQuery example and cross-browser solution, see the Related Question:
HTML5 event listener to scroll number input - Chrome only
@ Semyon Quail
There is a better solution for this. Blur removes focus from the input, and this is a side effect that you don't want. Instead, you should use evt.preventDefault. This prevents the default input behavior when scrolling through a user. Here is the code:
input = document.getElementById("the_number_input") input.addEventListener("mousewheel", function(evt){ evt.preventDefault(); }) One event listener to manage all of them
This is similar to @Semyon Perepelitsa's answer in pure js, but a bit simpler as it puts one event listener in the document element and checks if the focused element is a number:
document.addEventListener("mousewheel", function(event){ if(document.activeElement.type === "number"){ document.activeElement.blur(); } }); If you want to disable the scroll behavior of values ββin some fields, but not others , just do this instead:
document.addEventListener("mousewheel", function(event){ if(document.activeElement.type === "number" && document.activeElement.classList.contains("noscroll")) { document.activeElement.blur(); } }); with this:
<input type="number" class="noscroll"/> If there is a noscroll class at the input, it will not change when scrolling, otherwise everything will remain the same.
You must stop the mousewheel event first:
- Disable it using
mousewheel.disableScroll - Intercept it using
e.preventDefault(); - Removing focus from
el.blur();
The first two approaches stop the window from scrolling, and the last removes focus from the element; both of which are undesirable results.
A el.blur() is to use el.blur() and reorient the element after the delay:
$('input[type=number]').on('mousewheel', function(){ var el = $(this); el.blur(); setTimeout(function(){ el.focus(); }, 10); }); You can simply use the onwheel HTML attribute .
This option does not affect the scrolling of other page elements.
And adding a listener for all inputs does not work on inputs dynamically created at the back.
Alternatively, you can remove input arrows using CSS.
The answers provided do not work in Firefox (Quantum). The event listener must be changed from the mouse wheel to the wheel:
$(':input[type=number]').on('wheel',function(e){ $(this).blur(); }); This code works on Firefox Quantum and Chrome.
For those who work with React and are looking for a solution. I found that the easiest way is to use the onWheelCapture propeller in the Input component as follows:
onWheelCapture={e => { e.target.blur() }}
Trying to solve this problem for myself, I noticed that you can actually save the page scrolling and input focus by disabling number changes by trying to re-trigger the intercepted event in the parent element <input type="number"/> on which it was caught, just:
e.target.parentElement.dispatchEvent(e); However, this leads to an error in the browser console and probably does not guarantee that it will work everywhere (I tested only on Firefox), since this is intentionally incorrect code.
Another solution that works well, at least in Firefox and Chromium, is to temporarily create an <input> readOnly , for example:
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); }); One side effect I noticed is that it can cause the field to flicker for a split second if you have a different style for readOnly fields, but at least in my case this doesn't seem to be a problem.
In the same way (as explained in James's answer), instead of changing the readOnly property readOnly you can blur() field and then focus() bring it back, but again, depending on the styles used, some flickering may occur.
Alternatively, as mentioned in other comments here, you can simply call preventDefault() on the event instead. Assuming that you only process wheel events on numerical inputs that are in focus and under the mouse cursor (which means the three conditions above), the negative impact on user interaction will be practically zero.
function fixNumericScrolling() { $$( "input[type=number]" ).addEvent( "mousewheel", function(e) { stopAll(e); } ); } function stopAll(e) { if( typeof( e.preventDefault ) != "undefined" ) e.preventDefault(); if( typeof( e.stopImmediatePropagation ) != "undefined" ) e.stopImmediatePropagation(); if( typeof( event ) != "undefined" ) { if( typeof( event.preventDefault ) != "undefined" ) event.preventDefault(); if( typeof( event.stopImmediatePropagation ) != "undefined" ) event.stopImmediatePropagation(); } return false; } Typewriter Option
Typescript needs to know that you are working with HTMLElement to ensure type safety, otherwise you will see many errors like Property 'type' does not exist on type 'Element' .
document.addEventListener("mousewheel", function(event){ let numberInput = (<HTMLInputElement>document.activeElement); if (numberInput.type === "number") { numberInput.blur(); } }); Below css fix looks simpler:
input[type=number]::-webkit-inner-spin-button, input[type=number]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }