按向上箭头时防止文本输入中的默认行为

时间:2022-06-29 03:40:27

I’m working with basic HTML <input type="text"/> text field with a numeric value.

我正在使用带有数值的基本HTML 文本字段。

I’m adding JavaScript event keyup to see when user presses arrow up key (e.which == 38) – then I increment the numeric value.

我正在添加JavaScript事件密钥以查看用户何时按下向上箭头键(e.which == 38) - 然后我增加数值。

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.

代码运行良好,但有一件事让我感到困扰。当我按下向上箭头键时,Safari / Mac和Firefox / Mac都会在最开始移动光标。据我所知,这是每个文本字段的默认行为,这是有道理的。

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:

开头的跳跃发生在keydown上,但即使有了这些知识,我也无法防止它发生。我尝试了以下方法:

input.addEventListener('keydown', function(e) {
    e.preventDefault();
}, false);

Putting e.preventDefault() in keyup event doesn’t help either.

将e.preventDefault()置于keyup事件中也无济于事。

Is there any way to prevent cursor from moving?

有没有办法阻止光标移动?

5 个解决方案

#1


28  

To preserve cursor position, backup input.selectionStart before changing value.

要保留游标位置,请在更改值之前备份input.selectionStart。

The problem is that WebKit reacts to keydown and Opera prefers keypress, so there's kludge: both are handled and throttled.

问题是WebKit对keydown做出反应而Opera更喜欢按键,因此存在kludge:两者都被处理和限制。

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

#2


13  

I found that a better solution is just to return false; to prevent the default arrow key behavior:

我发现一个更好的解决方案就是返回false;防止默认箭头键行为:

input.addEventListener("keydown", function(e) {
    if (e.keyCode === 38 || e.keyCode === 40) return false;
}, false);

#3


4  

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!

是的,这很容易!

#4


0  

I tested the code and it seems that it cancels the event but if you don't press the arrow for very short time - it fires keypress event and that event actually moves cursor. Just use preventDefault() also in keypress event handler and it should be fine.

我测试了代码,它似乎取消了事件,但是如果你没有按下箭头很短的时间 - 它会触发按键事件并且该事件实际上会移动光标。只需在keypress事件处理程序中使用preventDefault(),它应该没问题。

#5


-1  

Probably not. You should instead seek for a solution to move the cursor back to the end of the field where it was. The effect would be the same for the user since it is too quick to be perceived by a human.

可能不会。您应该寻求一种解决方案,将光标移回到字段的末尾。对于用户来说效果是相同的,因为它太快被人类察觉。

I googled some and found this piece of code. I can't test it now and it is said to not to work on IE 6.

我搜索了一些,发现了这段代码。我现在无法测试,据说不能在IE 6上运行。

textBox.setSelectionRange(textBox.value.length, textBox.value.length);

#1


28  

To preserve cursor position, backup input.selectionStart before changing value.

要保留游标位置,请在更改值之前备份input.selectionStart。

The problem is that WebKit reacts to keydown and Opera prefers keypress, so there's kludge: both are handled and throttled.

问题是WebKit对keydown做出反应而Opera更喜欢按键,因此存在kludge:两者都被处理和限制。

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

#2


13  

I found that a better solution is just to return false; to prevent the default arrow key behavior:

我发现一个更好的解决方案就是返回false;防止默认箭头键行为:

input.addEventListener("keydown", function(e) {
    if (e.keyCode === 38 || e.keyCode === 40) return false;
}, false);

#3


4  

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!

是的,这很容易!

#4


0  

I tested the code and it seems that it cancels the event but if you don't press the arrow for very short time - it fires keypress event and that event actually moves cursor. Just use preventDefault() also in keypress event handler and it should be fine.

我测试了代码,它似乎取消了事件,但是如果你没有按下箭头很短的时间 - 它会触发按键事件并且该事件实际上会移动光标。只需在keypress事件处理程序中使用preventDefault(),它应该没问题。

#5


-1  

Probably not. You should instead seek for a solution to move the cursor back to the end of the field where it was. The effect would be the same for the user since it is too quick to be perceived by a human.

可能不会。您应该寻求一种解决方案,将光标移回到字段的末尾。对于用户来说效果是相同的,因为它太快被人类察觉。

I googled some and found this piece of code. I can't test it now and it is said to not to work on IE 6.

我搜索了一些,发现了这段代码。我现在无法测试,据说不能在IE 6上运行。

textBox.setSelectionRange(textBox.value.length, textBox.value.length);