前端 BUG 录 - input 数字校验异常问题
思否
前端BUG录 调试 表单 Vue 转载自 SegmentFault
前两天才分享了 input 的属性、特征。昨天就有个小伙伴踩雷了。所以素材又有了
小伙伴做的是实名认证(移动端)相关的功能,然后有个位置校验了只能输入数字。
小伙伴发出了灵魂质疑:为什么 1. 没事 1.. 就被清空了? 这个问题告诉我们喝一点没事,“一點點”不行。
复现代码
功能是基于 Vue 来实现的。
<input id="define" type="number" placeholder="最多9999" @keyup="inputKeyUp">
下面是 methods 里面的方法
inputKeyUp: function inputKeyUp(a) {
var val = document.getElementById('define').value;
var limitNum = 9999,
limitLen = 4;
val = val.replace(/\.+|\s+/g, '');
if (val.length > limitLen) {
val = val.substr(0, limitLen);
}
if (Number(val) > limitNum) {
val = limitNum;
}
if (val == '0') {
val = 1;
}
if (0 < Number(val) && Number(val) <= limitNum) {
this.changeBG = 1;
} else {
this.changeBG = 0;
}
document.getElementById('define').value = val;
}
复现地址: https://www.lilnong.top/static/html/input-number-validity.html
问题截图
分析问题提取关键信息
- 移动端、只能输入数字。
input实现输入,有type="number"。- 监听
inputKeyUp,内部获取.value,经过正则过滤/\.+|\s+/,长度截取.substr(0, limitLen)。 - 通过
.value再赋值回去
那我们一个一个排查
type 改为默认的 text。
我们会发现 . 的问题得到了解决。
那么为什么 number 不行?而 text 可以?
可以看到我们都测试了 1..,但是 number 的时候我们获取到的并没有 .。运用我们前两天学到的知识,把 validationMessage 打出来看看。
https://segmentfault.com/a/1190000037538101
回想一下H5校验的特征是什么? 只获取正确的参数。 因为这个特征导致我们没有获取到内容,然后在后面赋值的时候被清空了。
正则处理&长度截断
长度截断没什么好说的。
那我们来看一下正则/\.+|\s+/获取到的是点 \.和空白符 \s。
感觉 /[^0-9]/ 更好
但是里面不会处理数字,所以和清空没有关系
赋值操作
经过测试可以发现,异常的数值是无法赋值的。
问题成因?
因为使用了 type="number" 然后导致异常值直接无法获取,又因为底部有一个赋值,所以导致被清空。
- 不使用
type="number"。 如果是pc端,那么没啥毛病,如果是移动端。那么type="number"其实可以调起一个专用的数字键盘 - 动态改
type="number"这个方案也不行,因为会导致键盘被替换。 - 自己实现一个键盘
微信公众号:前端linong
原文:SegmentFault