[UX Improvement] Disable mouse wheel behavior on number type inputs
There is annoying behaviour that should not exist IMHO for UX's sake: when you scroll on an <input type="number"> you can change input when you have the focus on it which is not user-friendly at all since the mouse wheel is almost exclusively used for scrolling page. As a result, people are typing a value, then trying to scroll further for another input and then changing the input value without even noticing for the majority.
I don't know what is implemented in React that changes how it is handled in most browsers. I have tried to track down the event which is modifying the input without success. But if you try vanilla javascript in, let's say, Chrome then you don't have this ugly behaviour. :man_shrugging:
For illustration purposes:
- React behaviour: https://codesandbox.io/s/silly-feynman-ic8f9p
- Vanilla behaviour: https://codesandbox.io/s/laughing-fog-rkrc6s
Another reference: https://stackoverflow.com/questions/68260072/why-can-we-update-a-value-of-a-number-input-using-mouse-wheel
Can someone explain why and where in the code wheel is changing the input? Or why it is not like that in vanilla JS (for most browsers)?
And maybe deciding to change the default behaviour to something more user-friendly could be discussed?
It's NOT only stupid thing in react.
Here is some (simplified) code from a project.
<div
// React uses `focusIn/focusOut` under the hood
onFocus={() => setPauseOnHover(true)}
onBlur={() => setPauseOnHover(false)}
/>
And a strange thing is happening with onMouseLeave
I want to work on this issue
For React.js, I was able to fix the issue by adding "onWheel={(e) => e.target.blur()}" inside the input tag.
Yeah, it is a workaround I use too. But still, it is lousy UX because it will unfocus the input field while scrolling which is not what users expect. It does not happen for other inputs so why for number one?!
I want to mention, that react rendering affects also inputs that are draw outside the React component.
https://codesandbox.io/s/wheel-problem-5nz2b5?file=/src/index.js:110-282
@vvscode indeed, as exposed in my first codesandbox, but I forgot to mention it clearly. Thanks for mentioning that annoying side effect!
It's possible to get correct behaviour with adding event to the ref, but if you are using forwardRef it's became tricky.
const domRef = React.useRef<HTMLInputElement>();
React.useEffect(() => {
const preventInputScroll = (e: WheelEvent) => e.preventDefault();
domRef.current?.addEventListener('wheel', preventInputScroll);
return () => {
domRef.current?.removeEventListener('wheel', preventInputScroll);
};
});
return (<input type='number' ref='domRef' />);
document.body.addEventListener("wheel", (ev) => {
const target = ev.composedPath()[0] as HTMLElement;
if (target.matches('input[type="number"]')) {
target.blur();
}
});
solves the problem globally (including shadow DOM)
@vvscode Thanks for the code snippets but unfortunately this is still a lousy behaviour, not a real transparent solution. And thus this cannot be an excuse to not fix this issue.
@qvantor Thanks for the code snippet too but last time I checked calling preventDefault() have the side effect of preventing the user from scrolling when the input is focused, again not a proper fix but could be a lousy workaround for some people though.
@shikhar13012001 any news about your help proposal or this has just been ignored?
may not be a React bug, all you need to reproduce this is a passive wheel listener attached to some element (does not have to be the input element)
https://codesandbox.io/s/friendly-browser-ueyekx
Hey, I want to work on your issues try to give me this UX improvement . thank you !!