我想要一个PIN输入表单,其中每个字符都输入一个单独的html输入。
我正在尝试在javascript中捕获keyup事件,以便我可以将焦点更改为下一个输入元素,从而使用户无需通过鼠标单击或选项卡自行更改它。
除非用户输入非常快,否则它正在工作。例如,如果用户非常快速地键入字符“1”和“2”,我发现第一个输入现在正确地具有字符“1”,而第二个输入仍然是空的,并且焦点已移至第三个输入
为什么呢?
以下是代码:
$(document).ready(function () {
$('.pinchar').keyup(function (e) {
if (
(e.which == 8) //backspace
|| (e.which == 46) // del
|| (e.which == 9) // tab
|| (e.which == 13) // return
|| (e.which == 27) // esc
|| (e.which == 37) // arrow
|| (e.which == 38) // arrow
|| (e.which == 39) // arrow
|| (e.which == 40) // arrow
|| (e.which == 27) // esc
|| (e.which == 20) // CAPS LOCK
|| (e.which == 17) // Ctrl
|| (e.which == 18) // Alt
|| (e.which == 16)) { //shift
return false;
} else {
$(this).parent().next().find('.pinchar').focus();
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="enterPINTable">
<tr>
<td>
<input name="txtPIN1" id="txtPIN1" class="pinchar" size="1">
</td>
<td>
<input name="txtPIN2" id="txtPIN2" class="pinchar" size="1">
</td>
<td>
<input name="txtPIN3" id="txtPIN3" class="pinchar" size="1">
</td>
<td>
<input name="txtPIN4" id="txtPIN4" class="pinchar" size="1">
</td>
</tr>
</table>
答案 0 :(得分:3)
keyup
将失败,然后在释放之前按下另一个键。然后,事件的顺序为keydown 1
,keydown 2
,keyup 1
,keydown 2
。但是,在keydown
(和keypress
)之后生成字符时,在这种情况下,在第一个input
事件之前,keyup
中已经有两个字符。
而是尝试input
事件:
$('.pinchar').on('input', function (e) {
// ... etc.
任何更改都会立即触发。
但要正确处理其他键,您还需要捕获keydown
事件(对于箭头和退格键)。
我会建议这段代码:
function step(inp, dir, clr) {
if (clr) $(inp).val('');
var $next = $(inp).parent()[['prev','next'][dir]]().find('.pinchar');
if (!$next.length) $next = $(inp);
$next.focus();
setTimeout(function () {
$next.select();
}, 0);
return false;
}
$(document).ready(function () {
$('.pinchar').on('focus', function () {
$(this).select(); // always select the "whole" (1 char) text
});
$('.pinchar').on('keydown', function (e) {
// arrows
if (e.which == 37 || e.which == 38) return step(this, 0);
if (e.which == 39 || e.which == 40) return step(this, 1);
// backspace
if (e.which == 8) return step(this, 0, 1);
});
$('.pinchar').on('input', function (e) {
step(this, 1);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="enterPINTable">
<tr>
<td>
<input name="txtPIN1" id="txtPIN1" class="pinchar" size="1">
</td>
<td>
<input name="txtPIN2" id="txtPIN2" class="pinchar" size="1">
</td>
<td>
<input name="txtPIN3" id="txtPIN3" class="pinchar" size="1">
</td>
<td>
<input name="txtPIN4" id="txtPIN4" class="pinchar" size="1">
</td>
</tr>
</table>
请注意,上面的代码旨在始终选择当前字符,因此如果您键入另一个字符,它将替换当前字符。
left
,right
,tab
,shift
+ tab
,backspace
和delete
密钥也可以正常工作可以预料。
答案 1 :(得分:2)
在这种情况下,Keypress更适合。
问题是密钥被触发得很晚,即在keydown和keypress之后。
订单如下:
按下键时,会立即触发keydown事件。在该事件中,该值不会打印在屏幕上。触发该按键后,此时将打印该值。
在两个事件之后,当您将手指从钥匙上抬起时,触发了键盘。
因此,当您快速按下两个键时,它们的按键会快速连续调用(在屏幕上打印值时),因此值将打印在同一输入上,然后调用两个键,将焦点转移到下一个输入的下一个(将它们留空是因为在按键期间已经打印了值。)
$(document).ready(function () {
$('.pinchar').keypress(function (e) {
$(this).parent().next().find('.pinchar').focus();
});
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="enterPINTable">
<tr>
<td>
<input name="txtPIN1" id="txtPIN1" class="pinchar" size="1">
</td>
<td>
<input name="txtPIN2" id="txtPIN2" class="pinchar" size="1">
</td>
<td>
<input name="txtPIN3" id="txtPIN3" class="pinchar" size="1">
</td>
<td>
<input name="txtPIN4" id="txtPIN4" class="pinchar" size="1">
</td>
</tr>
</table>
&#13;