写作时间: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文本框中输入应该是可以直接同步在文本框的,我试了一下,没有按照预期效果。后续如果有看过我文章并且做过研究的,记得给我留言。