每当我们需要验证码或者支付码的时候,总会出现一下的样式
一看就知道,这明显六个input修改样式之后排列在一起,这就出现了一个问题:你不可能让用户每输入完一个数字之后就手动将光标定位到下一个input吧?用户大人那么懒,难道你指望他点击六次,不会吧(白岩松问号)
这时候我们就需要实现一个小模块,具体需求是:每次输入完一个字母之后,光标会自动定位到下个input盒子,并且按“delete”键的时候,光标也会自动退回到上一格。
首先是html框架:既然要输入数字,那么我们的type就应该设置成number,这样就不需要数字验证,此外第一个input设置为autofocus,让第一个input自动定位
<div class="box">
<!-- maxlength规定输入的最多字符,这里的话只能输入一个数字 -->
<!-- autofocus属性让页面打开的时候第一个输入框自动focus聚焦 -->
<!-- 一个小错误,转变为number属性之后,实际上maxlength不起作用 -->
<input type="number" maxlength="1" autofocus>
<input type="number" maxlength="1">
<input type="number" maxlength="1">
<input type="number" maxlength="1">
<input type="number" maxlength="1">
<input type="number" maxlength="1">
</div>
然后是样式表部分:我们重新设定了宽度,并将input的选中加亮取消
<style>
input {
width: 15px;
/* outline属性去除选中后的加量边框 */
outline: none;
}
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
}
</style>
此外我们还将input的内部数字选择转轮取消掉了,也就是下图的上下箭头部分
下面是js部分
<script>
// 获取input组成的合集
let inputs = document.querySelectorAll("input")
// 利用循环添加事件,注意这里的let,涉及到块级作用域
for (let i = 0; i < inputs.length; i++) {
inputs[i].addEventListener('input', function (e) {
console.log(e);
// 下面这行用于重新赋值,这个data是新输入的值,用来取代原先占位的value
inputs[i].value = e.data
// input的number类型有个坑,就是maxlength不起作用,能输入好几个数字,于是我需要截取头一个数字
inputs[i].value = inputs[i].value.slice(0, 1)
})
inputs[i].addEventListener('keyup', function (e) {
// 当输入的是Backspace(也就是delete)并且并不在第一个input的时候,光标向前一格
if (e.key == 'Backspace' && i != 0) {
inputs[i].previousElementSibling.focus()
} else {
// 当不处于最后一个光标并且本input的值不是空的时候,进入下一个光标
if (i == inputs.length - 1 || !inputs[i].value) return
inputs[i].nextElementSibling.focus()
}
})
}
</script>
在写这个时候遇到了很多坑,现以问题的形式记录如下:
1.keypress能不能监听delete键?
2.change和input有啥不同?
3.这里的keyup能改成keydown吗?
4.如果我input的type换成text,怎么去判断数字,能否接受输入法的检验?
5.怎么改成vue版本?
当然这只是我菜鸡本人的一点小小想法,应该会有更好的实现方法,自己实现一下再简陋都是好的,感谢阅读。