前言:
首先是条码扫描头在设备管理器中可以看到就是一个键盘设备。
然后屏幕也是个光源,扫描枪不能扫屏幕,条码打印到纸上就行了。
然后各家厂商都可以设置扫描结果设置自定义前缀后缀,搜索设备型号找到文档,扫描指定的设置码即可,我这边使用的是Honeywell(霍尼韦尔) MS5145条码阅读器的默认设置,
即扫描成功后(发出滴声 滴声可关闭) 键盘自动输入:扫描结果(条码)+ 回车。
代码主要是利用JS中的键盘监听事件,然后设置定时器去校验。
然后我的业务需求是13位的纯数字的商品编号条码和16位的数字加字母的MAC地址,在同一页面实现扫码自动输入(输入前校验)。
通过keydown获取到HTML DOM Event 对象
event包含的属性中event.keyCode、event.charCode和event.which都可以获知按下了哪个键盘按键,其中包含了浏览器兼容性问题可参考这篇文章:
其中获取到数值都是对应的键盘ASCII码。
在前考虑过数组下标取值最快 还有些查找算法,后来想到这边的业务需求只需输入数字和字母所以选择了在js中使用键值对。
使用了下面的键值对:
使用keyDate[ascii值]就可以获得按键
// 键盘ASCII码:"按键"
var keyData={
//数组部分有每个按键有两个对应的两个ascii值是因为
//主键盘区的数组和Num数字辅助键盘区(键盘右侧数字小键盘)同一数字的ascii值不同
48:"0",96:"0",
49:"1",97:"1",
50:"2",98:"2",
51:"3",99:"3",
52:"4",100:"4",
53:"5",101:"5",
54:"6",102:"6",
55:"7",103:"7",
56:"8",104:"8",
57:"9",105:"9",
//键盘中大写A和小写a的ascii值是相同的 我的需求中必须大写字母 所以:
65:"A",66:"B",67:"C",68:"D",
69:"E",70:"F",71:"G",72:"H",
73:"I",74:"J",75:"K",76:"L",
77:"M",78:"N",79:"O",80:"P",
81:"Q",82:"R",83:"S",84:"T",
85:"U",86:"V",87:"W",88:"X",
89:"Y",90:"Z"};
然后我们
我们在页面中加入这段代码
<script>
$(document).keydown(function (event) {
console.log(keyData[event.keyCode]+"----"+event.keyCode);
});
</script>
使用扫描枪扫描(系统操作焦点需要在浏览器 当前页面)
chrome控制台中打印以下
全大写的原因在keyDate[]代码注释中有说明
我们可以看到他在切换大小写的时候还按了一次left shift按键(需注意)
接下来看扫描成功后按键的输入速度:
//键盘事件中加入
console.log(new Date().getTime()/1000);
约0.2秒输入完成(可能所使用的电脑的性能有一定关系 所以接下来的监听重置时间设置0.5秒是较为保险的一个时间)
下面是出项目中抽离的可分享代码 可直接使用的demo:
<!DOCTYPE html>
<html>
<head>
<title>扫码枪demo</title>
</head>
<script type="text/javascript" src="http://lib.sinaapp.com/js/jquery/3.1.0/jquery-3.1.0.min.js"></script>
<body>
mac地址:<input type="text" name="macAddress" id="macAddress" placeholder="16位" /><br>
产品编号:<input type="text" name="productNumber" id="productNumber" placeholder="13位" />
</body>
<script>
var temporaryKeyList="";
var timer="";
$(document).keydown(function (event) {
var key=event.keyCode;
//依次是屏蔽 回车 左Shift
if (key==13||key==16) {
return;
}
//如果有定时器就不创建新的check方法
if (!timer) {
temporaryKeyList="";
timer=setInterval("checkInput()",500);
}
temporaryKeyList+=keyData[key];
});
function checkInput(){
if (temporaryKeyList.length==13) {
$("#productNumber").val(temporaryKeyList);
}
if (temporaryKeyList.length==16) {
$("#macAddress").val(temporaryKeyList);
}
//清除定时器
clearTimeout(timer);
timer=null;
}
var keyData={
48:"0",96:"0",
49:"1",97:"1",
50:"2",98:"2",
51:"3",99:"3",
52:"4",100:"4",
53:"5",101:"5",
54:"6",102:"6",
55:"7",103:"7",
56:"8",104:"8",
57:"9",105:"9",
65:"A",66:"B",67:"C",68:"D",
69:"E",70:"F",71:"G",72:"H",
73:"I",74:"J",75:"K",76:"L",
77:"M",78:"N",79:"O",80:"P",
81:"Q",82:"R",83:"S",84:"T",
85:"U",86:"V",87:"W",88:"X",
89:"Y",90:"Z"};
</script>
</html>
大概就是逻辑就是发生键盘按键之后去监听接下来的0.5秒的键盘事件
如果符合13位16位(我的需要)就认为它是扫码枪输入,这种方案可能扫描枪扫描的输入的0.5秒内,刚好碰到键盘,但是不符合我的长度要求。即失败,重新扫描即可,规避了错误输入。
但是还是有错误的几率 所以我在checkInput()中加入了我的特殊要求校验(代码未列出),可自行加入校验规则。
如果有更好的方案或者案例可以@我一下
顺颂时祺