2

前两天才分享了 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

问题截图

image.png

分析问题提取关键信息

  1. 移动端、只能输入数字。
  2. input 实现输入,有 type="number"
  3. 监听 inputKeyUp,内部获取 .value,经过正则过滤 /\.+|\s+/,长度截取 .substr(0, limitLen)
  4. 通过 .value 再赋值回去

那我们一个一个排查

type 改为默认的 text

我们会发现 . 的问题得到了解决。

那么为什么 number 不行?而 text 可以?
image.png

可以看到我们都测试了 1..,但是 number 的时候我们获取到的并没有 .运用我们前两天学到的知识,把 validationMessage 打出来看看。

https://segmentfault.com/a/1190000037538101

image.png

回想一下H5校验的特征是什么只获取正确的参数
因为这个特征导致我们没有获取到内容,然后在后面赋值的时候被清空了。

正则处理&长度截断

长度截断没什么好说的。
那我们来看一下正则/\.+|\s+/获取到的是\.空白符 \s

image.png

感觉 /[^0-9]/ 更好

image.png

但是里面不会处理数字,所以和清空没有关系

赋值操作

经过测试可以发现,异常的数值是无法赋值的。
image.png

问题成因?

因为使用了 type="number" 然后导致异常值直接无法获取,又因为底部有一个赋值,所以导致被清空。

  1. 不使用 type="number"
    如果是pc端,那么没啥毛病,如果是移动端。那么 type="number" 其实可以调起一个专用的数字键盘
  2. 动态改 type="number"
    这个方案也不行,因为会导致键盘被替换。
  3. 自己实现一个键盘

微信公众号:前端linong

clipboard.png


linong
29.2k 声望9.5k 粉丝

Read-Search-Ask