当输入文本字段达到最大长度时移动焦点

26
我有一个信用卡号码表单。该号码被分为四部分,就像真正的信用卡一样。
我想在表单中添加JavaScript功能,当用户在一个字段中输入四个字符时,焦点会自动转移到下一个标签,但不会在最后一个标签中发生。通过这样做,用户不必键入“tab”键来移动焦点。
在标签中添加一些额外的类、id或名称都可以。
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>MoveFocus</title>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
    <script type="text/javascript" charset="utf-8">
     $(function() {
     // some code goes here.
    });
    </script>
</head>


<body>
  <form action="post.php" method="post" accept-charset="utf-8">
    <input type="text" value="" id="first" size="4" maxlength="4"/> -
    <input type="text" value="" id="second" size="4" maxlength="4"/> -
    <input type="text" value="" id="third" size="4" maxlength="4"/> -
    <input type="text" value="" id="fourth" size="4" maxlength="4"/>
    <p><input type="submit" value="Send Credit Card"></p>
  </form>
</body>
</html>

3
当然,有些用户会按Tab键并漏掉某些字段。不要将字段分开,只需使用单个字段即可。这样对用户来说更加容易(而且这也是其他每个网站都在做的)。 - Quentin
6
虽然我并不代表所有用户,但是我讨厌那些要求输入电话号码、信用卡号码和社会安全号码的网站。我更喜欢那些把下一个按键解释为进入下一个框并开始输入的网站。在您的情况下,等待第五个按键,如果它是数字,则将焦点移到下一个框并将第一个字符设置为所按下的数字。如果是右箭头键,则移动到下一个框,并且不设置任何字符。这只是关于可用性方面的我的观点。 - jball
2
哦,如果用户在任何给定的框中输入最后一个字符时出错,他们可能希望退格键继续正常工作。 - Quentin
2
需要成立一个反自动对焦和切换标签的联盟。有些用户界面过于智能化,妨碍了正常使用。 - user195488
8个回答

30

我以前没有使用过这个工具,但它可以满足你的需求。你可以查看它的源代码以获取一些想法:

GitHub上的此插件

对于你的情况,你需要添加以下代码:

<script type="text/javascript" src="jquery.autotab.js"></script>
<script type="text/javascript">
$(document).ready(function() {
    $('#first').autotab({ target: '#second', format: 'numeric' });
    $('#second').autotab({ target: '#third', format: 'numeric', previous: '#first' });
    $('#third').autotab({ previous: '#second', format: 'numeric' });
});
</script>

感谢您向我介绍了一个很棒的插件。其他人建议使用“onchange()”,但似乎效果不佳。您提到的脚本使用keydown()keypress()keyup(),似乎是更好的解决方案。 - TK.

17

像其他人建议的那样,不要这样做。用户无法预料到您将自动标签定位到他们身上,这将让他们感到烦恼。您是否考虑过复制和粘贴信用卡信息的用户?使用四个字段到底有什么好处呢?

另外,并不是所有的信用卡都将其号码分成四组四个数字。例如,美国运通把它们分成三组数字。在这种情况下,动态添加和删除文本字段可能会引起麻烦。

相反地,请使用 Javascript 在适当的位置自动插入 空格,让光标前进而不是聚焦。数字中的第一个数字指示信用卡类型(5 是万事达卡,4 是 Visa,3 是美国运通等),因此您可以读取此信息以决定在何处添加空格。在提交时删除字符串中的空格。这种方法将为您和您的用户节省很多麻烦。


2
+1 - 当输入信用卡信息时,自动缩进是最令人讨厌的事情。特别是如果你犯了一个错误,需要返回时。 - Patrick

10

正如@Sander所建议的,实现自动切换的简单方法是:

jQuery("form input[type=text]").on('input',function () {
    if(jQuery(this).val().length == jQuery(this).attr('maxlength')) {
        jQuery(this).next("input").focus();
    }
});

更新 by @morespace54

oninput 是一个在 IE9+ 上支持的 html5 事件,因此您可以使用 keyup 替代。


只是想让大家知道,即使上面的代码在FF/Chrome/Safari/Opera上运行良好(感谢@Ouadie),我在IE上(Doh)也很难让它正常工作,即使在v8上也是如此。通过更改keyup的输入,我设法使其在IE中正常工作。所以它像这样: jQuery("form input[type=text]").on('keyup',function () { if(jQuery(this).val().length == jQuery(this).attr('maxlength')) { jQuery(this).next("input").focus(); } }); - morespace54
oninputIE9+ 版本才支持的,因此在 IE8 中无法使用。我会更新解决方案。谢谢 ;) - Ouadie
3
哦,我不知道IE9+使用input。谢谢。我希望有一天我们能生活在没有IE的世界里... ;) (翻译:Oh,我之前不知道IE9+会使用input。感谢。希望有一天我们能够生活在没有IE的世界...;)) - morespace54

7
如果你的表单字段是左右相邻的,就像你的例子一样,你可以简单地利用nextElementSibling来实现!

function skipIfMax(element) {
  max = parseInt(element.dataset.max)
  
  
  if (element.value.length >= max && element.nextElementSibling) {
    element.nextElementSibling.focus();  
  }
}
<input type="text" data-max=2 oninput="skipIfMax(this)"/>
<input type="text" data-max=3 oninput="skipIfMax(this)"/>
<input type="text" data-max=4 oninput="skipIfMax(this)"/>
<input type="text" data-max=5 oninput="skipIfMax(this)"/>


6

我强烈建议使用Masked Input jQuery 插件

使用方法如下:

$("#CreditCardNumber").mask("9999-9999-9999-9999");

这样做可以实现复制粘贴和占位符支持。

1
一个非常简单的解决方案可以像这样:
<script type="text/javascript">
    function input_onchange(me){ 
        if (me.value.length != me.maxlength){
            return;
        }
        var i;
        var elements = me.form.elements;
        for (i=0, numElements=elements.length; i<numElements; i++) {
            if (elements[i]==me){
                break;
            }
        }
        elements[i+1].focus();
    }
</script>
<form action="post.php" method="post" accept-charset="utf-8">
    <input type="text" value="" id="first" size="4" maxlength="4"
        onchange="input_onchange(this)"
    /> -
    <input type="text" value="" id="second" size="4" maxlength="4"
        onchange="input_onchange(this)"
    /> -
    <input type="text" value="" id="third" size="4" maxlength="4"
        onchange="input_onchange(this)"
    /> -
    <input type="text" value="" id="fourth" size="4" maxlength="4"
        onchange="input_onchange(this)"
    /> -
    <p><input type="submit" value="Send Credit Card"></p>
</form>

谢谢。我在我的浏览器上尝试了(Firefox和Safari),但似乎不起作用。 - TK.
我已经将“me.value.length!=this.maxlength”更改为“me.value.length!=this.maxLength”,以使代码正常工作。我猜这只是一个小错误。 - ashofphoenix

0

我还没有测试过,但我认为这会起作用。当第四个字段完成时,它可能也会将焦点移动到按钮。

$("form input").change(function () {
    var maxLength = $(this).attr('maxlength');

    if($(this).val().length == maxLength) {
        $(this).next().focus();
    }
}

代码似乎运行不太好。我需要在填写4个字母后点击某个地方才能移动焦点。但还是谢谢,我明白了。 - TK.
1
啊,那是因为change只有在焦点移动时才会被调用,对于这个例子来说有点不太好用 :-)\,你可能需要挂钩keyup事件。 - Sander Rijken

0

这个表单没有四个字段,但它可以验证信用卡(完整性检查,不是 Luhn 算法!)。我必须告诉你,对于用户和自动制表而言,使用多个字段是多么的烦人。我建议你只使用一个字段。

来自 jquery 网站:

$("#myform").validate({
  rules: {
    field: {
      required: true,
      creditcard: true
    }
  }
});

/

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
                    "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <script src="http://code.jquery.com/jquery-latest.js"></script>
  <script type="text/javascript" src="http://dev.jquery.com/view/trunk/plugins/validate/lib/jquery.delegate.js"></script>
<script type="text/javascript" src="http://dev.jquery.com/view/trunk/plugins/validate/jquery.validate.js"></script>
<script type="text/javascript">
jQuery.validator.setDefaults({
    debug: true,
    success: "valid"
});;
</script>

  <script>
  $(document).ready(function(){
    $("#myform").validate({
  rules: {
    field: {
      required: true,
      creditcard: true
    }
  }
});
  });
  </script>
  <style>#field { margin-left: .5em; float: left; }
    #field, label { float: left; font-family: Arial, Helvetica, sans-serif; font-size: small; }
    br { clear: both; }
    input { border: 1px solid black; margin-bottom: .5em;  }
    input.error { border: 1px solid red; }
    label.error {
        background: url('http://dev.jquery.com/view/trunk/plugins/validate/demo/images/unchecked.gif') no-repeat;
        padding-left: 16px;
        margin-left: .3em;
    }
    label.valid {
        background: url('http://dev.jquery.com/view/trunk/plugins/validate/demo/images/checked.gif') no-repeat;
        display: block;
        width: 16px;
        height: 16px;
    }
</style>
</head>
<body>

<form id="myform">
  <label for="field">Required, creditcard (try 446-667-651): </label>
  <input class="left" id="field" name="field" />
  <br/>
  <input type="submit" value="Validate!" />
</form>

</body>
</html>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接