input change获取改变之前的值和改变之后的值_input[type='number'],ios安卓采坑记

近日,在为公司维护移动端H5代码的过程中,因为平台实现的差异,中间踩了不少坑。借此机会记录一下,也希望大家能有个了解,少走弯路。这一切的一切,都要从一个简单的需求开始说起。

某日,产品、测试反馈,对于ios机型,输入框获取焦点时弹出的数字键盘没有小数点,因此不可输入小数。而安卓端没有问题。我眉头一皱,觉得事情并不简单那是不可能的。这还能有啥幺蛾子,以我多年(一年....)的开发经验,这明显是输入框的类型写错了。于是我不慌不忙的打开编辑器,经过启动项目,找到问题页面,打开Chrome控制台,审查元素等一系列操作之后。果然不出我所料,目前的input的type为tel,在ios上没有小数点也是正常的。问题找到了,那解决起来也就很快,replace('tel','number')。做完这一切,我找到测试,叹了口气道:你们提的这个bug啊,着实是不好弄。我在百度上Google了许久,也没有哪个Stack Overflow的大神能给出解决方案。‘那可怎么办啊,app马上就要上线了,项目经理还催着呢’,果不其然,测试小哥听后急的要死。''莫慌,尽管这个问题很难弄,但是经过我一番神乎其技的操作,还是顺利的解决了,你可以去验证了。''说完这一切,我便潇洒的走开了。留下了眼里冒着小星星的小哥独自崇拜。事了拂衣去,深藏功与名,我果真是那么的不可揣摩。

我回到座位上,开始回味刚才这美好的过程。不一会,就见小哥踏着小碎步朝我走来。心中暗自窃喜:小哥这么客气,还亲自过来道谢,怪不好意思的。不料事与愿违,小哥一过来就质问我:''这个问题真的改好了吗?怎么现在问题更多了?ios上不仅可以输入小数,汉字也可以,而且安卓可以输入多个小数点。''我听完这样的描述,一脸懵。但转念一想,觉得不太可能出现这样的事。一方面input类型已经设为number,弹出的键盘是不可输入汉字的。另外,这个输入框的值是被监听的,一旦有非数字或小数点的字符就会被剔除。所以我觉得有些蹊跷,便让小哥重现一遍给我看。我果真是不到黄河心不死,然而事实就是小哥所说的那样。之所以ios可以输入汉字是因为键盘上方留存有用户之前输入的历史信息。这个问题定位到了之后,安卓端可以输入连续的小数点是怎么一回事呢?按理说正则不会没用的。

于是我让小哥稍安勿躁,回到座位上开始寻找问题的原因。既然是正则在此时无效了,那便要看看此时输入框中的值到底是多少。话不多说,console.log(e.target.value)当我输入正常的数字时,一切都是那么正常。而当输入连续的两个小数点时,问题便出现了,此时输入框里的值突变为空,而此后无论再怎么输入,结果都是空,但输入框里显示的值却不是空,而是之前所有输入的字符。''难怪此时正则会失效,一旦错误输入后值就为空了''

问题找到了,是什么原因导致的呢。经过一番寻找,最终得到这样一个答案:number类型的input输入框会对输入的值做验证,如果不是一个合法的浮点数(NaNInfinity),输入框的值将变为空。原因找到以后,我便思索对策。既然输入框本身 的值不可靠,那便监听键入的单个字符的字符码,如果不是在数字和小数点对应的字符码中,便返回即可。思路清晰,说干就干。监听keydown事件,获取keyCode,判断code值一气呵成。为了以防万一,这次我在浏览器上自测了一遍,表现的非常符合预期。做完这一切,我把小哥喊来,信誓旦旦的告诉他这次肯定没有问题了。

午后的阳光十分温暖,照在身上痒痒的,让人不自觉的想要入睡。我靠在座位上,享受这看似美好的美好,心里总觉得并不是很稳。果不其然,一会的功夫,小哥又朝我走来,并且面带愠色。我开始有些慌了。暗自嘀咕:不该再有问题啊。没等他质问我,我拿了他的测试机自己操作了起来。不可思议的是,刚才所做的完全没有效果,所有的问题依然存在。''完全没有道理啊,在浏览器上是完全正常的,怎么到了app上就失效了呢',难道webview中的输入框不能获取到keyCode吗?',为了验证这个猜想,也为了能实时的测试,我用RN启动了一个本地的项目,在其中嵌入了一个webview,链接到这个页面,开启新一轮的调试。为了能在app上感知keydown事件触发时的keyCode,我使用了alert。结果让人意外,在pc上可以获取的keyCode,在app里是无法得到正确的结果的,除了删除为8,其它均为229。这样的结果真是让人无语。

没想到,看似简单的需求竟然隐藏了如此多的问题。为了解决问题,我开始寻找新的方案。过程不再赘述,以下给出三种方案:

  1. 自定义键盘
    自己实现一个数字键盘,模拟输入框
    优点:不存在平台兼容问题,以及上述的原生输入框的各样限制,可控性高
    缺点:由于是模拟的输入框,因此没有光标,也不能实现在值的中间修改。(可以模拟光标,但实现复杂)
  2. input、textInput事件inputtextInput事件的事件对象有一个data属性,值就是此时键入的实际的字符。它们的区别在于textInput事件对象e.target.value对应的是上一轮的结果,即不包括当前键入字符的值,而input事件对应的为键入后的值。
    优点:平台兼容性好
    缺点:暂未发现
  3. 修改键盘类型
    input的类型选用tel,在ios端设置field.keyboardType = UIKeyboardTypeDecimalPad,使得弹出的键盘带有小数点
    优点:快捷简单,可以保持现有代码较小的改动
    缺点:需要原生开发的小伙伴支持
    上述方案我用的是第一种,也是因为ui设计了不同于系统的键盘。第三种方法暂未测试,如有错误还请见谅。

开发果真是个费脑子的活,机器的诡异有时让人抓破脑袋,一阵无语。最后送大家一句谏言:生发不容易,且挠且珍惜。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值