Prevent default behavior in text input while pressing arrow up
Solution 1
To preserve cursor position, backup input.selectionStart
before changing value.
The problem is that WebKit reacts to keydown
and Opera prefers keypress
, so there's kludge: both are handled and throttled.
var ignoreKey = false;
var handler = function(e)
{
if (ignoreKey)
{
e.preventDefault();
return;
}
if (e.keyCode == 38 || e.keyCode == 40)
{
var pos = this.selectionStart;
this.value = (e.keyCode == 38?1:-1)+parseInt(this.value,10);
this.selectionStart = pos; this.selectionEnd = pos;
ignoreKey = true; setTimeout(function(){ignoreKey=false},1);
e.preventDefault();
}
};
input.addEventListener('keydown',handler,false);
input.addEventListener('keypress',handler,false);
Solution 2
I found that a better solution is just to return false;
to prevent the default arrow key behavior:
input.addEventListener("keydown", function(e) {
if (e.key === 'ArrowUp' || e.key === 'ArrowDown') return false;
}, false);
Solution 3
Actually, there is a better and simpler method to do this job.
$('input').bind('keydown', function(e){
if(e.keyCode == '38' || e.keyCode == '40'){
e.preventDefault();
}
});
Yes, it is so easy!
riddle
Updated on October 20, 2020Comments
-
riddle over 3 years
I’m working with basic HTML
<input type="text"/>
text field with a numeric value.I’m adding JavaScript event
keyup
to see when user presses arrow up key (e.which == 38
) – then I increment the numeric value.The code works well, but there’s one thing that bugs me. Both Safari/Mac and Firefox/Mac move cursor at the very beginning when I’m pressing the arrow up key. This is a default behavior for every
<input type="text"/>
text field as far as I know and it makes sense.But this creates not a very aesthetic effect of cursor jumping back and forward (after value was altered).
The jump at the beginning happens on
keydown
but even with this knowledge I’m not able to prevent it from occuring. I tried the following:input.addEventListener('keydown', function(e) { e.preventDefault(); }, false);
Putting
e.preventDefault()
inkeyup
event doesn’t help either.Is there any way to prevent cursor from moving?
-
riddle almost 15 yearsThanks. Actually updating input.value will result in cursor moving back at the end. So I might detect cursor’s position and then restore it after change is made (if it’s in the middle of number, for example). But I’m still looking for better solution, if it’s available.
-
riddle almost 15 yearsBusted it! Thanks a lot, it’s perfect. :)
-
Manish Singh over 10 yearsThanks man. The idea is to use the keydown event instead of keyup.
-
CmdrMoozy almost 10 yearsRight - keydown is the trick. Note that returning false seems to stop the event's propagation entirely, whereas
preventDefault()
will let the input box ignore the event, while still allowing other listeners to handle it as it bubbles up. -
Mario J Vargas almost 10 years@Lukas , your solution worked best for me. However, I'm calling
e.preventDefault();
instead of returningfalse
. The latter didn't achieve the freezing of the up-arrow key behavior. Thanks for posting an alternate, simpler solution. -
darylhedley over 9 yearsThis is the correct answer! I had to use the keydown event to stop the cursor moving and then the keyup event to get the input value when needed
-
NotJay over 8 yearsUp vote for "kludge"! Worked for me, thanks for the answer.
-
Nurul Huda over 4 yearsUsing e.code === 'ArrowUp' || e.code === 'ArrowDown' will make the code is much easier to read.
-
Robert Kujawa almost 3 yearsPerfect solution! Saved me so much time, I'm using Vue and all I had to do is
<input @keydown.up.down.prevent />
.