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.

+97
javascript html css html5 forms
Mar 15 2018-12-12T00:
source share
13 answers

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.)

+78
Dec 30 '14 at 11:23
source share
 $(document).on("wheel", "input[type=number]", function (e) { $(this).blur(); }); 
+28
Nov 19 '16 at 18:06
source share
 input = document.getElementById("the_number_input") input.addEventListener("mousewheel", function(event){ this.blur() }) 

http://jsfiddle.net/bQbDm/2/

For a jQuery example and cross-browser solution, see the Related Question:

HTML5 event listener to scroll number input - Chrome only

+19
Feb 11 '13 at 11:03
source share

@ 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(); }) 
+13
Sep 20 '13 at 12:27
source share

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.

+13
Jul 26 '16 at 11:45
source share

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); }); 
+6
Jun 25 '15 at 19:49
source share

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.

 input[type="number"]::-webkit-outer-spin-button, input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; } input[type="number"] { -moz-appearance: textfield; } 
 <input type="number" onwheel="this.blur()" /> 
+6
Jun 28 '18 at 6:40
source share

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.

+2
Apr 03 '18 at 7:55
source share

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() }}

+2
Nov 29 '18 at 12:36
source share

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.

+1
May 22 '19 at 6:47
source share
 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; } 
0
May 02 '16 at 11:00
source share

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(); } }); 
0
03 sept. '19 at 18:53
source share

Below css fix looks simpler:

 input[type=number]::-webkit-inner-spin-button, input[type=number]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; } 

Link

-four
Jan 28 '16 at 22:16
source share



All Articles