jQuery 一旦达到 maxlength 值,就聚焦下一个输入

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15595652/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 15:24:12  来源:igfitidea点击:

Focus next input once reaching maxlength value

javascriptjqueryiterationcounter

提问by O P

How can I focus the next input once the previous input has reached its maxlength value?

一旦前一个输入达到其 maxlength 值,如何聚焦下一个输入?

a: <input type="text" maxlength="5" />
b: <input type="text" maxlength="5" />
c: <input type="text" maxlength="5" />

If a user pastes text that is greater than the maxlength, ideally it should spill into the next input.

如果用户粘贴的文本大于 maxlength,理想情况下它应该溢出到下一个输入。

jsFiddle:http://jsfiddle.net/4m5fg/1/

jsFiddle:http : //jsfiddle.net/4m5fg/1/

I must stress that I do notwant to use a plugin, as I'd much rather learn the logic behind this, than use something that already exists. Thanks for understanding.

我必须强调,我希望使用的插件,因为我宁愿学习逻辑背后,不是使用的东西已经存在。感谢您的理解。

回答by Joseph Lennox

No jQuery used and is a very clean implementation:

没有使用 jQuery,是一个非常干净的实现:

  • Reads from the maxlength attribute.
  • Scales to any number of inputs inside of your container.
  • Automatically finds the next input to focus.
  • No jQuery.
  • 从 maxlength 属性读取。
  • 扩展到容器内的任意数量的输入。
  • 自动查找下一个要聚焦的输入。
  • 没有jQuery。

http://jsfiddle.net/4m5fg/5/

http://jsfiddle.net/4m5fg/5/

<div class="container">
a: <input type="text" maxlength="5" />
b: <input type="text" maxlength="5" />
c: <input type="text" maxlength="5" />
</div>

..

..

var container = document.getElementsByClassName("container")[0];
container.onkeyup = function(e) {
    var target = e.srcElement || e.target;
    var maxLength = parseInt(target.attributes["maxlength"].value, 10);
    var myLength = target.value.length;
    if (myLength >= maxLength) {
        var next = target;
        while (next = next.nextElementSibling) {
            if (next == null)
                break;
            if (next.tagName.toLowerCase() === "input") {
                next.focus();
                break;
            }
        }
    }
    // Move to previous field if empty (user pressed backspace)
    else if (myLength === 0) {
        var previous = target;
        while (previous = previous.previousElementSibling) {
            if (previous == null)
                break;
            if (previous.tagName.toLowerCase() === "input") {
                previous.focus();
                break;
            }
        }
    }
}

回答by mgibsonbr

You can watch for input in the fields and test its value:

您可以观察字段中的输入并测试其值:

$("input").bind("input", function() {
    var $this = $(this);
    setTimeout(function() {
        if ( $this.val().length >= parseInt($this.attr("maxlength"),10) )
            $this.next("input").focus();
    },0);
});

Working demo.

工作演示

The setTimeoutis there to ensure the code will only run afterthe input is completed and the value updated. Binding inputensures most types of input will trigger the event, including key presses, copy/paste (even from mouse) and drag & drop (though in this case, the latter won't work, since the focus was on the draggable, not the droppable).

setTimeout是有保证的代码将只运行输入完成和值更新。绑定input确保大多数类型的输入都会触发事件,包括按键、复制/粘贴(甚至来自鼠标)和拖放(尽管在这种情况下,后者将不起作用,因为焦点在可拖动对象上,而不是可丢弃)。

Note: on some older browsers, you might also need to bind propertychange.

注意:在一些较旧的浏览器上,您可能还需要绑定propertychange.



If a user pastes text that is greater than the maxlength, ideally it should spill into the next input.

如果用户粘贴的文本大于 maxlength,理想情况下它应该溢出到下一个输入。

To do that, you might need to remove the maxlengthattribute using JavaScript (to be able to capture the full input), and implement that functionality yourself. I made a small example, relevant parts below:

为此,您可能需要maxlength使用 JavaScript删除该属性(以便能够捕获完整输入),并自己实现该功能。我做了一个小例子,相关部分如下:

$("input").each(function() {
    var $this = $(this);
    $(this).data("maxlength", $this.prop("maxlength"));
    $(this).removeAttr("maxlength");
})

This removes the attribute, but saves it in data, so you can access it later.

这将删除该属性,但将其保存在 中data,以便您以后可以访问它。

function spill($this, val) {
    var maxlength = $this.data("maxlength");
    if ( val.length >= maxlength ) {
        $this.val(val.substring(0, maxlength));
        var next = $this.next("input").focus();
        spill(next, val.substring(maxlength));
    }
    else
        $this.val(val);
}

Here the max length logic is reintroduced in JavaScript, as well as getting the "discarded" part and using it in a recursive call to spill. If there's no next element, the call to datawill return undefinedand the loop will stop, so the input will be truncated in the last field.

这里在 JavaScript 中重新引入了最大长度逻辑,以及获取“丢弃”部分并在对spill. 如果没有下一个元素,则调用data将返回undefined并且循环将停止,因此输入将在最后一个字段中被截断。

回答by Antony

You can use plain JavaScript:

您可以使用纯 JavaScript:

See DEMO.

演示

Check the character length with el.value.length. If it is equal to the maximum value, move to the next field by using focus(). Bind this function to the keyup event with onkeyupso that the function fires every time after the user keys in a character.

用 来检查字符长度el.value.length。如果它等于最大值,则使用 移动到下一个字段focus()。将此函数绑定到 keyup 事件,onkeyup以便每次用户键入字符后都会触发该函数。

var a = document.getElementById("a"),
    b = document.getElementById("b"),
    c = document.getElementById("c");

a.onkeyup = function() {
    if (this.value.length === parseInt(this.attributes["maxlength"].value)) {
        b.focus();
    }
}

b.onkeyup = function() {
    if (this.value.length === parseInt(this.attributes["maxlength"].value)) {
        c.focus();
    }
}

回答by btevfik

if you are going to have many fields you can do something like this.

如果你有很多领域,你可以做这样的事情。

basically on keyupget the length of the input and then compare it to the maxlength, if matches, then focusonto the next input field.

基本上是keyup获取输入的长度,然后将其与最大长度进行比较,如果匹配,则focus进入下一个输入字段。

http://jsfiddle.net/btevfik/DVxDA/

http://jsfiddle.net/btevfik/DVxDA/

$(document).ready(function(){
    $('input').keyup(function(){
        if(this.value.length==$(this).attr("maxlength")){
            $(this).next().focus();
        }
    });
});

回答by Sri Sri M

If you are adding input text fields dynamically then you can try this.

如果您要动态添加输入文本字段,则可以尝试此操作。

This will re-inject the script into the DOM and works Perfectly.

这会将脚本重新注入 DOM 并完美运行。

$('body').on('keyup', '#num_1',function(){
  if (this.value.length === parseInt(this.attributes["maxlength"].value)) {
    $('#num_2').focus();
  }
})
$('body').on('keyup','#num_2', function(){
   if (this.value.length === parseInt(this.attributes["maxlength"].value)) {
    $('#num_3').focus();
  }
})
<input type="text" class="form-control" name="number" maxlength="3" id="num_1">
<input type="text" class="form-control" name="number" maxlength="3" id="num_2">
<input type="text" class="form-control" name="number" maxlength="4" id="num_3">

回答by irejwanul

If you're focused on creating card(debit/credit) number input type. Then clean an easily manageable jQuery version as follows:

如果您专注于创建卡(借记/信用卡)号码输入类型。然后清理一个易于管理的 jQuery 版本,如下所示:

/*..............................................................................................
* jQuery function for Credit card number input group
......................................................................................................*/
            // make container label of input groups, responsible
            $('.card-box').on('focus', function(e){
                $(this).parent().addClass('focus-form-control');
            });
            $('.card-box').on('blur', function(e){
                $(this).parent().removeClass('focus-form-control');
            });
            $('.card-box-1').on('keyup', function(e){
                e.preventDefault();
                var max_length = parseInt($(this).attr('maxLength'));
                var _length = parseInt($(this).val().length);
                if(_length >= max_length) {
                    $('.card-box-2').focus().removeAttr('readonly');
                    $(this).attr('readonly', 'readonly');
                }
                if(_length <= 0){
                    return;
                }
            });
            $('.card-box-2').on('keyup', function(e){
                e.preventDefault();
                var max_length = parseInt($(this).attr('maxLength'));
                var _length = parseInt($(this).val().length);
                if(_length >= max_length) {
                    $('.card-box-3').focus().removeAttr('readonly');
                    $(this).attr('readonly', 'readonly');
                }
                if(_length <= 0){
                    $('.card-box-1').focus().removeAttr('readonly');
                    $(this).attr('readonly', 'readonly');
                }
            });
             $('.card-box-3').on('keyup', function(e){
                e.preventDefault();
                var max_length = parseInt($(this).attr('maxLength'));
                var _length = parseInt($(this).val().length);
                if(_length >= max_length) {
                    $('.card-box-4').focus().removeAttr('readonly');
                    $(this).attr('readonly', 'readonly');
                }
                if(_length <= 0){
                    $('.card-box-2').focus().removeAttr('readonly');
                    $(this).attr('readonly', 'readonly');
                }
            });
            $('.card-box-4').on('keyup', function(e){
                e.preventDefault();
                var max_length = parseInt($(this).attr('maxLength'));
                var _length = parseInt($(this).val().length);
                if(_length >= max_length) {
                    return;
                }
                if(_length <= 0){
                    $('.card-box-3').focus().removeAttr('readonly');
                    $(this).attr('readonly', 'readonly');
                }
            });
/*..............................................................................................
* End jQuery function for Credit card number input group
......................................................................................................*/
/* Hide HTML5 Up and Down arrows. */
                                input[type="number"]::-webkit-outer-spin-button, input[type="number"]::-webkit-inner-spin-button {
                                    -webkit-appearance: none; margin: 0;
                                }
                                input[type="number"] { -moz-appearance: textfield; }
                                .card-box {
                                    width: 20%; display: inline-block; height: 100%; border: none;
                                }
                                
                                .focus-form-control {
                                    border-color: #66afe9; outline: 0;-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);
                                        box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);
                                }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="form-control" style="padding: 0; max-width: 300px; ">
                                        <input class="card-box card-box-1" type="number" id="CreditCard_CardNumber1" required step="1" minlength="4" maxlength="4" pattern="[0-9]{4}" value="" placeholder="0000"
                                            onClick="this.setSelectionRange(0, this.value.length)" oninput="this.value=this.value.slice(0,this.maxLength||'');this.value=(this.value < 1) ? ('') : this.value;"/> 
                                        <input class="card-box card-box-2" type="number" id="CreditCard_CardNumber2" readonly required step="1" minlength="4" maxlength="4" pattern="[0-9]{4}" value="" placeholder="0000"
                                            onClick="this.setSelectionRange(0, this.value.length)" oninput="this.value=this.value.slice(0,this.maxLength||'');this.value=(this.value < 1) ? ('') : this.value;" />
                                        <input class="card-box card-box-3" type="number" id="CreditCard_CardNumber3" readonly required step="1" minlength="4" maxlength="4" pattern="[0-9]{4}" value="" placeholder="0000"
                                            onClick="this.setSelectionRange(0, this.value.length)" oninput="this.value=this.value.slice(0,this.maxLength||'');this.value=(this.value < 1) ? ('') : this.value;" />
                                        <input class="card-box card-box-4" type="number" id="CreditCard_CardNumber4" readonly required step="1" minlength="4" maxlength="4" pattern="[0-9]{4}" value="" placeholder="0000"
                                            onClick="this.setSelectionRange(0, this.value.length)" oninput="this.value=this.value.slice(0,this.maxLength||'');this.value=(this.value < 1) ? ('') : this.value;" />
                                    </div>

回答by Surya R Praveen

Updated btevfikcode, Onkeyup or onkeydown will create issue as you won't be able to delete the previous input on tab navigation. It will be tough to edit or change the text inside the input box as it will be limited to maxlength. So we can use oninput event to achieve the task.

更新的btevfik代码、Onkeyup 或 onkeydown 将产生问题,因为您将无法删除标签导航上的先前输入。编辑或更改输入框中的文本会很困难,因为它会被限制为 maxlength。所以我们可以使用oninput事件来实现任务。

DEMO

演示

HTML

HTML

<ul>
<li>a: <input type="text" maxlength="5" /></li>
<li>b: <input type="text" maxlength="3" /></li>
<li>c: <input type="text" maxlength="5" /></li>
<li>d: <input type="text" maxlength="3" /></li>
<li>e: <input type="text" maxlength="6" /></li>
<li>f: <input type="text" maxlength="10" /></li>
<li>g: <input type="text" maxlength="7" /></li>
</ul>

Javascript

Javascript

$(document).ready(function(){
    $('input').on("input", function(){
        if($(this).val().length==$(this).attr("maxlength")){
            $(this).next().focus();
        }
    });
});

CSS

CSS

ul {list-style-type:none;}
li {padding:5px 5px;}

回答by Babir

Verified Answer have one issue which focus previous field if previous field have valid length

如果前一个字段具有有效长度,已验证的答案有一个问题,它关注前一个字段

I have Modified Above Answer to fix complete length of previous tag

我修改了上面的答案以修复上一个标签的完整长度

var container = document.getElementsByClassName("container")[0];
    container.onkeyup = function(e) {
    var target = e.srcElement || e.target;
    var maxLength = parseInt(target.attributes["maxlength"].value, 10);
    var myLength = target.value.length;
    if (myLength >= maxLength) {
        var next = target;
        while (next = next.nextElementSibling) {
            if (next == null)
                break;
            if (next.tagName.toLowerCase() === "input") {
                next.focus();
                break;
            }
        }
    }
    // Move to previous field if empty (user pressed backspace)
    else if (myLength === 0) {
         var previous = target;
       // Move to previous field if backspace is pressed
        if (code == 8) {
            previous = previous.previousElementSibling;
            if (previous != null) {
                if (previous.tagName.toLowerCase() === "input") {
                    previous.focus();
                }
            }
        } else {
            while (previous = previous.previousElementSibling) {
                if (previous == null)
                    break;
                if (previous.tagName.toLowerCase() === "input") {
                    var mLength = parseInt(previous.attributes["maxlength"].value, 10);
                    var pMyLength = previous.value.length;
                    // Move to previous field if it does not have required length
                    if (mLength == pMyLength) {
                        break;
                    } else {
                        previous.focus();
                        break;
                    }
                }
            }
        }
    }
}