解決中文狀態下掃描槍掃描錯誤

解決中文狀態下掃描槍掃描錯誤

寫作時間:2019-11-7 11:05:39

問題描述

今天項目上遇到反饋過來的問題:前端input輸入去後臺覈對時,使用鍵盤輸入覈對成功,使用掃描槍輸入覈對失敗。原因很明顯:掃描槍掃出來的字符串肯定是錯誤的。

後續跟進反饋,中文狀態下掃描槍出現這種問題。

大概猜測下,中文狀態下掃描快遞包裹,比如中通快遞單號爲:
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>
<!--其中e代表鍵盤監聽事件擡起鍵盤的那個指定的建-->

複製以上代碼,自己嘗試下每個的效果。發現如下:

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 example</title>
</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 example</title>
    </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文本框中輸入應該是可以直接同步在文本框的,我試了一下,沒有按照預期效果。後續如果有看過我文章並且做過研究的,記得給我留言。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章