解決中文狀態下掃描槍掃描錯誤
寫作時間:2019-11-7 11:05:39
問題描述
今天項目上遇到反饋過來的問題:前端input輸入去後臺覈對時,使用鍵盤輸入覈對成功,使用掃描槍輸入覈對失敗。原因很明顯:掃描槍掃出來的字符串肯定是錯誤的。
後續跟進反饋,中文狀態下掃描槍出現這種問題。
大概猜測下,中文狀態下掃描快遞包裹,比如中通快遞單號爲:
首先說明下掃描槍的原理:完全模擬鍵盤輸入!也就是說,掃描出來的字符串也是逐個進行輸出,也是有鍵盤的所有監聽事件的。
再看上面的快遞單號:中文狀態下”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文本框中輸入應該是可以直接同步在文本框的,我試了一下,沒有按照預期效果。後續如果有看過我文章並且做過研究的,記得給我留言。