前两天才分享了 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"
这个方案也不行,因为会导致键盘被替换。 - 自己实现一个键盘
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。