H5 中数字 input 的处理

4,759 阅读3分钟

对于数字相关的输入,我们会使用 HTML5 提供的 type="number" 来处理。number 类型的 input 只允许我们输入与数字有关的内容(0-9,小数点、正负号以及表示科学计数法的 e)

可以在下面的输入框中尝试一下 type="number" 的 input :

然而在实际的业务场景中,type="number" 并不能满足我们,比如禁止输入小数点和正负号的需求。因为在输入 . + - e 的时,inputonChange 事件时不会有响应的,除非当输入是一个合法的数字。例如我们输入 ----1 或者 ....3 时,onChange 并不会有任何反应。也即我们失去了对 input value 的判断机会。

当然,利用 onKeyUp 或者 onKeyDown 来监听按键来进行控制也是可以的。不过我更喜欢换回 type="text" 配合正则进行处理。这招在 PC 端上问题不大,但是在移动端上却会产生另一个问题——唤起键盘的样式。


在移动端中,input 的 type="number" 唤起的是数字键盘;type="text" 时唤起的是英文键盘。因此当遇到禁止输入小数点、正负号的需求时,要么说服产品,要么就只能自己想办法。不过现实中我们往往会(无奈地)选择后者。

一个虚拟键盘应该可以满足各种需求。不过,自己实现虚拟键盘不仅费时费力,很可能还要根据不同的系统进行样式的修改,如果没有现成的库显然是不太实际的方案。

那又能否利用 onKeyUponKeyDown 事件呢?然而手机(我的是小米)上 . + - 的按键都是 229,很显然这是没有办法做判断的。如果第一个就输入 . + -,那么 e.target.value 是空。即便是合法的数字如 -1+1 也不满足禁止输入 + - 的需求。

那么是不是就没有办法了呢?再次梳理一下需求,在移动端我们需要点击 input 时唤起数字键盘,并且不允许输入非数字外的值(包括小数点、正负号)。

查看 MDN 之后发现 HTML5 中 input 有个 tel 的 type。<input type="tel" /> 正好可以满足我们的需求。顾名思义 type="tel" 是用来输入电话号码的,唤起的是号码键盘(与数字键盘很相似)。尽管不是真正的数字键盘(iOS 上可以看到两者的区别),但也基本满足了我们的需求了。而另一个最重要的特点就是,type="tel"type="text" 类似,可以利用 onChange 对所有输入进行监听,这也就意味着我们可以对输入的值进行控制了。

尽管这是一个投机取巧的办法,不过用在移动端上确实非常有用。下次如果遇到移动端的数字输入的情况,不妨可以考虑一下 type="tel" 这个属性。