记网页文本框中的一些坑
记网页文本框中的一些坑
最近在在做需求的时候有碰到一个六位数密码输入框的需求,用户输入只能输入数字,不能输入其他字符,同时移动端要求唤起的是数字键盘。
很容易想到这样的实现:添加一个输入框,使其隐藏——width=0或者是opacity=0都可以,然后在其上覆盖一层label,和外面的展示的假输入框等大,这样用户点击label就能focus到输入框上。最后将输入框内的内容渲染到假输入框上,即能达到很好的效果。
实际实现使用了vue,实现过程中发现了一些输入框的问题,在此做一个记录。
问题一、Number类型的输入框没有有效小数位时获取不到小数点
type=number类型的输入框中的内容如果没有有效的小数位,例如内容为:123. 此时获取该输入框的value,会发现是没有这个小数点的。
而且此时将其value修改为”123”,编辑框中的实际内容并不会变化。
但是在Firefox中,虽然获取到的value也不包含小数点,但是将其value修改为”123”,输入框的内容将会变成123。
实际上,一开始我的做法是如果Number输入框中输入小数,则实际值会变成向下取整。后来发现如果刚输入小数点的时候由于value不包含小数,且在chrome中修改其value为整数并不改变实际输入框内容,这就导致:
- 输入小数点的时候,输入框内容为”123.”,对应到的变量value为123,渲染结果也为123
- 再输入一位,此时输入框内容变成”123.4”,对应到的变量value向下取整为123,渲染结果仍然为123
- 那么我在密码框中输入123.4,其中.的那一次输入是无效的,有效输入应该是1234,而在这种情况下,值变成了123,和需要表现不符
问题二、Number类型的输入框可以输入无效值
这个问题的根源在于有些符号确实在数字中使用,但是如果符号的位置不对,整个数字不合法,并且其value会变成一个空字符串。
和前面的情况不一样,在这里对value赋值空字符串,确实可以清除掉不合法的内容。
但是对于vue框架来说就不是这样了,在使用vue框架的时候,并没有清除掉错误的内容,也就是说如果我开头的时候输入一个e,接下来无论输入什么都不会显示;或者在输入的过程中输入一个短横线,当前已经输入的内容会直接消失——这都是因为此时获取到的value为空字符串。
为什么会这样呢?个人推测这其实和vue的渲染方式有关。众所周知,vue生成的DOM其实并不是真实的DOM,实际上是一个虚拟DOM,在虚拟DOM发生变化之后,vue会对比实际DOM和虚拟DOM,然后高效地渲染内容。那么对于这里,由于该input元素在修改前后的value都为空字符串,自然没必要进行重渲染,也就不会清除掉无效的内容了。
问题三、iOS中隐藏输入框的问题
在iOS中,使用任何方式隐藏了输入框(已尝试:width: 0px,opacity: 0,left: -9999px),则输入框获取焦点的时候页面不会自动上滑。
当然这个问题解决起来也很简单,默认不隐藏,focus的时候再隐藏就好了,blur的时候要重新显示。
问题四、部分安卓手机上输入框宽度为0会导致输入反向
经过测试发现,在一些安卓手机上把输入框的宽度变成0会导致输入反向,即输入1、2、3,编辑框内容变成了321。
因此最后使用了opacity: 0而不是用width: 0的方式来隐藏输入框。