解决中文状态下扫描枪扫描错误

解决中文状态下扫描枪扫描错误

写作时间:2019-11-7 11:05:39

问题描述

今天项目上遇到反馈过来的问题:前端input输入去后台核对时,使用键盘输入核对成功,使用扫描枪输入核对失败。原因很明显:扫描枪扫出来的字符串肯定是错误的。

后续跟进反馈,中文状态下扫描枪出现这种问题。

大概猜测下,中文状态下扫描快递包裹,比如中通快递单号为:
Z T 103838237398 ZT103838237398 ZT103838237398
首先说明下扫描枪的原理:完全模拟键盘输入!也就是说,扫描出来的字符串也是逐个进行输出,也是有键盘的所有监听事件的。

再看上面的快递单号:中文状态下”ZT1“会输出什么?

在这里插入图片描述

以上也只是猜测,因为没有实际的扫码枪。但是问题还是需要解决的。

解决思路

解决思路1:不让输入中文!

<input type="text">

更改为

<input type="password">

可以完全解决输入中文的问题,但是不能显示明文。再加入一个text的input框,用于显示输入,password涌入接收输入。监听键盘按下或者抬起事件,每次时间后都把输入值从password传给text显示。具体代码如下:

<html>
    <head>
        <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
        <title>扫描枪中文状态输入汉字问题title>
    head>
    <body>
        <input type="password" id="password" >
        <input placeholder="请输入密码"  id="text" type="text"  disabled>
        <br/>文本框<input type="text" >
        <br/>密码框<input type="password">
        
        <script>
            var obj = {};
            Object.defineProperty(obj, 'txt', {
                get: function () {
                    return obj;
                },
                set: function (newValue) {
                    document.getElementById("password").value = newValue;
                    document.getElementById('text').value = newValue;
                   
                }
            });
            document.getElementsByClassName("pad-input")[0].addEventListener('keyup', function (e) {
                obj.txt = e.target.value;
            });
        script>
    body>
html>

复制以上代码,自己尝试下每个的效果。发现如下:

1、单纯的text文本框,是可以输入汉字的;

2、单纯的password密码框,是不能输入汉字,但是不会明文显示的;

3、在每次键盘“抬起事件”后,将password的值传给text,text可以正确显示。

至此,已经离完全解决问题很近了,此时,只要将标签重叠,使效果像只会明文显示的密码框。

最终解决:只用绝对定位(当然,如果项目中使用table的td放input也是一样的),自己加一写适合项目的style即可。demo如下:

<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
<title>Image preview exampletitle>
head>
<body>
     <div style="position: relative;width: 200px;">
           <input name="password" autocomplete="off" hidden id="password">
           <input type="password" autocomplete="off" class="pad-input" style="height: 30px;width: 100%;">
           <input placeholder="请输入密码"  id="show" type="text" style="position: absolute;left: 3px;top:50%;transform: translate(0,-50%);border: none;height: 28px;pointer-events: none;background: #fff;width: 98%;" disabled>

    div>
    <input type="text">

    <script>
        var obj = {};
        Object.defineProperty(obj, 'txt', {
            get: function () {
                return obj;
            },
            set: function (newValue) {
                document.getElementsByClassName("pad-input")[0].value = newValue;
                document.getElementById('show').value = newValue;
                document.getElementById('password').value = newValue;
            }
        });
        document.getElementsByClassName("pad-input")[0].addEventListener('keyup', function (e) {
            obj.txt = e.target.value;
        });
    script>
body>
html>

此时,问题已经解决了,一直到自己项目即可。这时候会有人有疑问了:都是监听单个键之后就立刻传值,那还有必要用password吗,就算是中文输入法,也是单个键抬起后就传递了啊。

好,我们做个例子看下,

<html>
    <head>
        <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
        <title>Image preview exampletitle>
    head>
    <body>
         <div style="position: relative;width: 200px;">
               <input type="password" autocomplete="off" class="pad-input" style="height: 30px;width: 100%;">
               <input placeholder="请输入密码"  id="show" type="text"  disabled>
               <br/>文本框<input type="text" id="test">
               <br/>密码框<input type="password">
        div>
        

        <script>
            var obj = {};
            Object.defineProperty(obj, 'txt', {
                get: function () {
                    return obj;
                },
                set: function (newValue) {
                    document.getElementsByClassName("pad-input")[0].value = newValue;
                    document.getElementById('show').value = newValue;
                    document.getElementById('test').value = newValue;
                   
                }
            });
            document.getElementsByClassName("pad-input")[0].addEventListener('keyup', function (e) {
                obj.txt = e.target.value;
            });
            document.getElementById("test").addEventListener('keyup',function(e){
                obj.txt = e.target.value;
            });
        script>
    body>
html>

复制上面的代码看下,在汉字“文本框”后的输入框中输入(保持中文输入法)。发现输入,就算单个键有监听事件,但是没有任何传值。

原因是因为中文输入法在没有Enter或者backspace或者数字触发的时候是拦截了浏览器对键盘的监听(只恨对onkeyup说明,其他的没测试,不敢乱说),关于这部分,查询了相关做过测试的文章,请参考

https://blog.csdn.net/ole_triangle_java/article/details/79084162

文章有句话,其中一个,比较有意思,说中文状态下

但是对于IE,依然能够获得keydown和keyup事件

意思是说,在IE中中文输入法的情况下,在text文本框中输入应该是可以直接同步在文本框的,我试了一下,没有按照预期效果。后续如果有看过我文章并且做过研究的,记得给我留言。

你可能感兴趣的:(前端)