你真的会使用input吗?

413 阅读2分钟

input在随意输入的时候玩玩没有太大问题,我们讲讲特殊场景,比如我们做一个输入金额的输入框,需要对金额进行校验。正常下,我们直接就把非法输入排除,但是这样真的可以吗?从js的角度肯定可以,但是从真实使用就未必了。

谈谈input type number 的坑

一个经典的限制金额代码是这样的

<input type="number" value={this.state.price} onInput={(e: React.ChangeEvent<HTMLInputElement>) => {
	const newValue = e.target.value.replace(/([^0-9.])|((?<=\d+\.\d{2})\d+)|((?<=^0)0+)|(^0(?=[1-9]))|((?<=\.\d*)\.)|(^\.)/g, '')
    console.log(newValue)
    this.setState({price: newValue})
}} />

测试也没问题,一切正常,不能输入中文和英文,只能输入数字,小数还只能2位数,爽歪歪,但是,真的没有问题了吗。

那我们输入一个12++看看,理论上只能只能展示12,但是一看屏幕,怎么没过滤掉++

经过排除发现,e.target.value压根拿不到value,这时候吓一跳,为啥输入了,但是拿不到值,是劳资电脑坏了? 重启试试。

重启还是一样,然后发现type="number"在搞鬼。

代码改良后,问题不见了

<input type="number" pattern="\d*" value={this.state.price} onInput={(e: React.ChangeEvent<HTMLInputElement>) => {
    // input type值为number的时候  value 无法正确反应结果   输入+符号,valu会得到空字符
    const value = e.target.value
    if(/^\d+\.?\d{1,2}$|^\d+$|^\d+\.$/.test(value)){
        this.setState({price: value})
    }else if(value == ''){
        const oldValue = this.state.price
        // 在有效数字大于1的时候,保留原来有效值
        if(oldValue.length > 1){
            this.setState(({price: oldValue}))
        }else{
            // input type值为number的时候   在包含+字符的时候直接设置空字符无效,所以先避开这种情况
            this.setState({price: '0'}, () => {
                this.setState(({price:''}))
            })
        }
    }
}} />

其实pc端完全可以把number改成text, 但是移动端不行,因为不设置数字的话,没办法弹出数字键盘,而是其他键盘给用户体验不好。

不如果可以的话,移动端用自己画的数字键盘,反正就几个按钮而已。

--完--