Javascript 如果用户键入速度过快,则为keyup和keydown事件

Javascript 如果用户键入速度过快,则为keyup和keydown事件,javascript,jquery,Javascript,Jquery,我不知道如何解决这个问题: 用户可以开始在输入字段中键入一些数值。键入数字后,光标将移动到下一个输入字段。 但是如果用户打字太快,这意味着如果两个数字之间没有键控键,那么它就不起作用了 因此,如果用户输入的是“12”,而不是“1”和“2”,则第一个输入字段中应该有值“1”,第二个输入字段中应该有值“2”,焦点应该设置为第三个输入字段 <form> <input type="password" maxlength="1" name="pin1" autofocus /&g

我不知道如何解决这个问题:

用户可以开始在输入字段中键入一些数值。键入数字后,光标将移动到下一个输入字段。 但是如果用户打字太快,这意味着如果两个数字之间没有键控键,那么它就不起作用了

因此,如果用户输入的是“12”,而不是“1”和“2”,则第一个输入字段中应该有值“1”,第二个输入字段中应该有值“2”,焦点应该设置为第三个输入字段

<form>
    <input type="password" maxlength="1" name="pin1" autofocus />
    <input type="password" maxlength="1" name="pin2" />
    <input type="password" maxlength="1" name="pin3" />
    <input type="password" maxlength="1" name="pin4" />
</form>

$('form input').on('keydown', function(event) {        
    if (event.shiftKey || event.which <= 47 || event.which >= 58)
        return false;

}).on('keyup', function (event) {
    if (event.currentTarget.value.length >= 1)
        $(event.currentTarget).next('input').focus();
});

$('forminput')。在('keydown',函数(事件){
if(event.shiftKey | | event.which=58)
返回false;
}).on('keyup',功能(事件){
如果(event.currentTarget.value.length>=1)
$(event.currentTarget).next('input').focus();
});

只需在keydown上添加keyup事件触发器上的代码即可

$('input').on('keydown', function(event) {   
    if (event.shiftKey || event.which <= 47 || event.which >= 58) {
        return false;
    }
    if (event.currentTarget.value.length >= 1) {
        $(event.currentTarget).next('input').focus();
    }
});
$('input')。在('keydown',函数(事件){
if(event.shiftKey | | event.which=58){
返回false;
}
如果(event.currentTarget.value.length>=1){
$(event.currentTarget).next('input').focus();
}
});

您是否尝试过结合这两种条件的
输入
事件,它将适用于多个用户操作,如
关键事件
剪切/粘贴事件
等:

$('forminput')。在('input keypress',函数(事件){
if(event.type==“keypress”&(event.shiftKey | | event.which=58))
返回false;
如果(event.currentTarget.value.length>=1)
$(event.currentTarget).next('input').focus();
});

要处理好这一点,你需要更加复杂一点,特别是如果用户使用paste输入PIN(他们不应该,但会)

我将删除
maxlength
,并在输入时将文本分布到输入端
keypress
是处理实际文本按键的最佳事件,当然我们需要
change
input

这是一个粗略的版本:

$('input').on('keypress input change', function(event) {
    setTimeout(handleInputs, 0);
});
function handleInputs() {
  var focussed = false;
  var inputs = $("input").get();

  // Collect the values
  var text = inputs.reduce(
    function(acc, input) {
      return acc + input.value;
    },
    ""
  );

  // ...adjust `text` here if you want...

  // Distribute the values
  inputs.forEach(function(input, index) {
    input.value = text.charAt(index);
    if (!focussed && !input.value) {
      console.log("Focussing " + this.name);
      input.focus();
      focussed = true;
    }
  });
}
现场示例:

$('input')。打开('keypress input change',函数(事件){
设置超时(handleInputs,0);
});
函数handleInputs(){
var聚焦=假;
变量输入=$(“输入”).get();
var text=inputs.reduce(
功能(acc,输入){
返回acc+input.value;
},
""
);
输入。forEach(函数(输入,索引){
input.value=text.charAt(索引);
如果(!focused&&!input.value){
console.log(“聚焦”+this.name);
input.focus();
聚焦=真实;
}
});
}

这是您可以用来处理所有(我认为)情况的方法:

$("input").on('change keyup paste', function(event) {
  if(event.which === 9) return; // tab pressed, keep default behaviour
  var char = this.value.slice(0, 1);
  if (!/\d/.test(char)) this.value = "";
  else $(this).next('input').focus();
});
(使用输入类型文本使其更清晰)


PS:我厌倦了JSFIDLE没有更新正确的版本。自从最新的JSFIDLE主要更新以来,这真的让我很头疼…

为什么不为4位数字构建一个输入?是因为你显示这些数字的方式吗?如果是这样,那么也许你应该用另一种方式来解决这个问题,或者做出让步,而不是冒着降低用户体验的风险。首先,你应该使用
keypress
事件,而不是
keydown
。根据键盘类型,
keydown
可能会返回意外行为,它不应用于
字符检查。您是否需要支持旧浏览器(例如IE8)?如果已经使用
输入
事件,更改和按键事件在这里不是多余的吗?在这里,这不仅仅处理数值,对吗?@A.Wolff:我对不支持
input
:-)的旧浏览器有点偏执因此,如果im'correct:)@A.Wolff:Good point,您应该添加
paste
,也可能添加
mouseup
(用于拖动)事件。如果我是在一个项目上做这项工作,我必须根据当前浏览器的使用情况再次研究它们。为什么要使用
setTimeout
?很好。但是如果我键入“12”,焦点应该在第三个输入字段上,但这将允许用户键入所有字符。我只需要允许数值。
输入
事件不是键盘事件,它不处理
事件。哪个
事件。Shift键
等等…啊!如A.Wolff所述,您可以向其添加一个以上的事件
按键
@user3142695关于这个问题的最后一个问题是:我在键入一个值后确实会进入下一个输入。一切正常。但是如果我点击
backspace
我想转到前面的输入并删除该内容:
if(event.type==“keypress”&&event.which==8)$(event.currentTarget.prev('input').focus()但这不起作用。
if(event.type==“keypress”)console.log(event.which)不会给我一个值。但我确实得到了每个角色的值。。。我不明白。。