小小扫码枪bug引发的思考

3,992 阅读4分钟

最近新公司发生了一件bug引发思考的事

产品需求

image.png

大致如上图,一个输入框,我们制作了自定义数字键盘,input框可以回显键盘的输入,并且,可以支持扫码枪输入回显

bug描述

在win 系统没有问题,但在安卓系统

  1. 每次自定义键盘输入时,还会吊起系统软键盘,且通过系统软键盘输入,input是无法回显的!键盘.jpg
  2. 不支持 扫码枪输入了

最讨厌研究 系统兼容性问题了,但问题出了,就得研究

我们先看一下,自定义数字键盘是怎么实现的?

在了解自定义键盘之前,我先问问大家,键盘输入会触发哪些事件?

对,就是这三个 keydown,keypress, keyup

如何控制Input框只回显数字呢?答案就是在keyDown事件里,通过捕获 event.key来获取用户按下的物理按键的值,非数字的值直接return就能做到了

那么言归正传,自定义键盘怎么实现呢?

其实到这边我们不难想到一个解决方案的思路就是,当按下自定义键盘时,我们模拟一个 keydown事件,并向获得焦点的input 派发这个keydown事件,那么就能模拟键盘输入了

上代码:

      const input = document.activeElement

      const event = document.createEvent('UIEvents')

      event.initUIEvent('keydown', true, true, window, 0)

      event.key = key

      event.keyCode = -1

      input.dispatchEvent(event)

扫码枪又是个啥?

就是这个东东:

image.png

去过超市的都看过吧

用扫码枪或者其他设备扫描图形码(条形码或其他码)后将其为文本输入, input需要识别到扫码枪输入结束,并回显input区,

其实扫码枪输入和用户键盘输入一样都可以触发keydown事件,派发给聚焦的input

那么问题来了?

怎样识别 扫码枪输入结束呢?

答案是onEnter事件

我们再来看看 安卓端出现的bug

1,为啥每次我们在自定义键盘上输入,会同时弹出系统软键盘呢??

问了下安卓侧RD,原来只要input获得焦点,系统键盘就会弹出

但是不聚焦,自定义键盘/扫码枪也没办法回显了呀?

难道真的无解了吗?这时候第n个知识点来了!用readOnly! readonly,对,就是它,

什么?readonly不是只读吗?有了它,相当于 用户无法输入,因此无法触发系统键盘,这个可以理解,但是,加上它之后,还有焦点吗?

这里有个问题要问大家,你知道readonly和disabled的区别吗?

答案就是在交互上,readonly 仍是可以聚焦的!disabled 就不能了

并且readOnly 是禁止用户输入,所以在允许聚焦的同时,又阻止了软键盘的弹出,这时我不禁感叹: 完美!

2,安卓为啥不支持扫码枪扫码了?

我们通过调试发现,在安卓上,keyDown事件 捕获到的event.key 是 Unidentified, 被我们判定为非数字,直接return了

那解法呢?我们神奇的发现,当我们解了bug1,加上readonly后,bug2也好了!

至于为啥它也好了,具体原因我还不清楚,以下是我的猜测:

前文我们提到,只要input聚焦,软键盘就会弹出,而扫码枪其实也可以看成一个特殊的键盘,可能两个键盘冲突导致 event.key 无法识别,加上readonly禁掉 软键盘后,冲突解除,自然event.key 也可以正常识别了

清楚原因的同学可以留言给我哈!我好想知道!!

反思来了

这件问题的最终解决方案只有一行代码,一个单词: readOnly

简单到令人发指,而且这个问题是一个刚来两天的新同学搞定的

我在想这一连串的故事,太神奇了

为啥这个困扰前辈同学包括我很久的问题,一个萌新一下子就解决了呢?虽然我也是萌新 image.png

readOnly可以 解决禁止软键盘弹出,网上的答案是有的,但是我pass了这个方案,

为什么呢?

  1. input相关基础差,我错误的认为readOnly是只读嘛,肯定会不带焦点啊,虽然禁用了软键盘,但是 扫码枪输入也不能回显了啊

  2. 当我看到 event.key 是 Unidentified 时,研究重点跑偏了

  3. 我觉得这可能某种程度上是一种 beginer’s luck, 因为当时新同学的任务是研究如何禁用软键盘,并没有提到其他扫码枪问题,可能这种心无旁骛反而成了事

  4. 工作中,尤其遇到一些诡异的兼容性问题,真的需要多尝试,不要被自己的想当然绑手绑脚

  5. 对于兼容性问题,因为要不断尝试,最好找到一种简单方便的调试方法,会大大加快调研进度

最后还是感谢一切的发生,收获了知识,也让我有冲动分享给大家我的一点小思考,感恩感恩!