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, 但是移动端不行,因为不设置数字的话,没办法弹出数字键盘,而是其他键盘给用户体验不好。
不如果可以的话,移动端用自己画的数字键盘,反正就几个按钮而已。
--完--