Javascript:如何最好地读取手持条码扫描仪?
Posted
技术标签:
【中文标题】Javascript:如何最好地读取手持条码扫描仪?【英文标题】:Javascript: How to read a hand held barcode scanner best? 【发布时间】:2014-03-05 04:57:27 【问题描述】:我希望能够通过手持扫描仪扫描条形码并使用 javascript 处理结果。
条码扫描器的工作方式几乎与键盘类似。它输出扫描/翻译的(条形码->数字)原始数据(对吗?)。实际上我只需要捕获输出并继续。但是怎么做呢?
这里有一些伪代码我想做的:
$(document).on("scanButtonDown", "document", function(e)
// get scanned content
var scannedProductId = this.getScannedContent();
// get product
var product = getProductById(scannedProductId);
// add productname to list
$("#product_list").append("<li>" + product.name + "</li>");
);
有什么想法(框架、插件、sn-ps)吗?
有什么条码扫描仪(硬件)推荐吗?
提前致谢!
我找到了this 和this 很好的问题,但我想了解有关处理的更多信息。在我的情况下,仅仅关注一个文本区域可能是不够的。
【问题讨论】:
【参考方案1】:您的伪代码不起作用,因为您无权访问扫描程序来捕获像scanButtonDown
这样的事件。您唯一的选择是 HID 扫描仪,其行为与键盘完全一样。要区分扫描仪输入和键盘输入,您有两种选择:基于计时器或基于前缀。
基于定时器
扫描仪输入字符的速度可能比用户(明智地)使用键盘输入的速度快得多。计算接收击键的速度并将快速输入缓冲到变量中以传递给您的getProductsId
函数。 @Vitall 写了一个reusable jQuery solution for catching barcode scanner input,你只需要捕捉 onbarcodescanned 事件。
基于前缀
大多数扫描仪都可以配置为所有扫描数据的前缀。您可以使用前缀开始拦截所有输入,一旦获得条形码,就停止拦截输入。
全面披露:我是制造手持扫描仪的 Socket Mobile, Inc. 的顾问。
【讨论】:
我知道这是一个旧帖子,但也想指出 HID 扫描仪也可能在输入末尾使用返回字符/键。 有没有办法去掉最后的回车/回车? @yeouuu 检查您的扫描仪文档。通常有一种方法可以禁用它,但它因扫描仪而异。或者,由于您正在捕获每个关键事件,您可以使用preventDefault
在每次扫描结束时“吞下”返回/输入键
我已经将基于计时器的解决方案倒入一个 vanilla-js 包中,就像一个魅力! npmjs.com/package/@itexperts/barcode-scanner【参考方案2】:
经过大量研究和测试,对我来说最有效的是从条形码扫描仪捕获输入,而无需关注表单输入。收听keydown
和textInput
事件。
textInput
事件的行为类似于paste
事件。然后它具有完整的条形码数据。就我而言,我正在寻找 UPC 条形码。 e.preventDefault()
防止条形码数据被插入到表单输入中:
document.addEventListener('textInput', function (e)
if(e.data.length >= 6)
console.log('IR scan textInput', e.data);
e.preventDefault();
);
我已经使用 CipherLab IR 扫描仪在 android 4.4 和 7.0 上对此进行了测试。
监听keydown
事件的示例。就我而言,我可以假设只要表单输入没有被聚焦,用户就在扫描条形码。
let UPC = '';
document.addEventListener("keydown", function(e)
const textInput = e.key || String.fromCharCode(e.keyCode);
const targetName = e.target.localName;
let newUPC = '';
if (textInput && textInput.length === 1 && targetName !== 'input')
newUPC = UPC+textInput;
if (newUPC.length >= 6)
console.log('barcode scanned: ', newUPC);
);
当然,您可以在keydown
事件侦听器中侦听e.keyCode === 13
,而不是检查字符串的长度来确定扫描。
并非所有红外扫描仪都会触发textInput
事件。如果你的设备没有,那么你可以检查它是否发出类似的东西:
monitorEvents(document.body);
在这里发现了这个监控技巧:How do you log all events fired by an element in jQuery?
【讨论】:
document.addEventListener('textInput'..
。为你工作?我只在inputs
获得关注时才收到该事件:\
@KevinJantzer 您正在开发 Cordova ios 应用程序吗?我今天才发现 iOS 不会在 web 视图中触发键盘事件,除非输入被聚焦。我修改了一个 Cordova iOS 插件来捕获键盘事件并将它们发送到我的应用程序:github.com/SimpleJoySolutions/cordova.externalkeyboard
我不是;我在安卓设备上使用网络应用清单。我最终弄清楚了我们如何使用 textInput
并在这里发布了代码:github.com/kjantzer/backbone-barcode-scanneri 你对 textInput
的评论帮助我找到了正确的方向!
很高兴听到您成功了!仅供参考,您在项目链接的末尾有一个额外的“i”。【参考方案3】:
我有点晚了,但我根据这里的一些答案解决了这个问题。
let code = "";
let reading = false;
document.addEventListener('keypress', e =>
//usually scanners throw an 'Enter' key at the end of read
if (e.keyCode === 13)
if(code.length > 10)
console.log(code);
/// code ready to use
code = "";
else
code += e.key; //while this is not an 'enter' it stores the every key
//run a timeout of 200ms at the first read and clear everything
if(!reading)
reading = true;
setTimeout(() =>
code = "";
reading = false;
, 200); //200 works fine for me but you can adjust it
【讨论】:
如果您正在寻找某些东西,这是您可以使用的解决方案。请注意,并非所有扫描仪都相同。对于某些蓝牙/更便宜的扫描仪来说,200 毫秒的超时可能不够。我建议允许客户调整此设置以满足他们的需求。 当我扫描带有 URL 的二维码时,返回 null。【参考方案4】:好的,这就是我的做法。我设置了扫描仪,添加了一个前缀(在我的例子中,我使用了 Ctrl+2 或 ascii 代码 002(控制代码),因此无法通过键盘轻松输入)和一个 ENTER,(随意如果您的条码数据可能包含回车,则在每次条码扫描后将其更改为使用 Ctrl+3 或 ascii 代码 003)。在 jQuery 中,我捕获 keypress 事件,并查找前缀。然后,我将所有内容捕获到一个字符串中,然后触发一个自定义事件,我的应用程序可以监听该事件。因为我阻止了按键事件,所以用户可以在文本字段中扫描条形码,这可以触发事件而不会影响他们正在做的任何事情。
此外,每个条形码都有一个我们使用的 1 位前缀,以识别扫描的条形码类型。例子:
E:员工徽章 S:主管徽章 I:项目编号let barcodeRead = '';
let readingBarcode = false;
let handleKeyPress = (e) =>
if (e.keyCode === 2)
// Start of barcode
readingBarcode = true;
e.preventDefault();
return;
if (readingBarcode)
e.preventDefault();
if (e.keyCode === 13) // Enter
readingBarcode = false;
const evt = $.Event('barcodeScan');
evt.state =
type: barcodeRead.substr(0, 1),
code: barcodeRead.substr(1),
;
$(window).trigger(evt);
barcodeRead = '';
return;
// Append the next key to the end of the list
barcodeRead += e.key;
$(window).bind('keypress', handleKeyPress);
因为有了这个前缀,我现在可以识别条形码的类型,看看是否应该在这个页面上处理它。示例:
$(window).bind('barcodeScan', (e) =>
if (e.state.type !== 'E')
alert('Please scan your employee badge only!');
else
$('#employee-badge').val(e.state.code);
);
【讨论】:
【参考方案5】:条码扫描器的工作方式几乎就像键盘一样。
这取决于型号。我用过的每一个都像键盘一样工作(至少就计算机而言)
它输出扫描/翻译的(条形码->数字)原始数据(对吗?)。
它输出键码。
$(document).on("scanButtonDown"
你可能想要keypress
,而不是scanButtonDown
。
查看事件对象以确定按下的“键”。
要确定何时扫描了整个代码,您可能会得到一个“数据结束”键(可能是空格或回车),或者您可能只需要计算输入的字符数。
【讨论】:
【参考方案6】:这里工作正常。 当输入有焦点和输入没有焦点
时它工作on_scanner() // init function
function on_scanner()
let is_event = false; // for check just one event declaration
let input = document.getElementById("scanner");
input.addEventListener("focus", function ()
if (!is_event)
is_event = true;
input.addEventListener("keypress", function (e)
setTimeout(function ()
if (e.keyCode == 13)
scanner(input.value); // use value as you need
input.select();
, 500)
)
);
document.addEventListener("keypress", function (e)
if (e.target.tagName !== "INPUT")
input.focus();
);
function scanner(value)
if (value == '') return;
console.log(value)
<input type="text" id="scanner" placeholder="scanner">
【讨论】:
【参考方案7】:这是对 Hanz Herdel 给出的答案的扩展,以防您使用 PosX 扫描仪或任何其他能够在字符开头添加特殊符号的扫描仪。在这种情况下,波浪号 (~) 符号:
let barcode = "";
let reading = false;
document.addEventListener("keydown", e =>
//console.log(e.key);
if (e.key == 'Enter')
if (barcode.length == 17)
if (barcode.charAt(0) == '~')
console.log(barcode);
barcode = "";
else
if (e.key != 'Shift')
barcode += e.key;
if (!reading)
reading = true;
setTimeout( () =>
barcode = "";
reading = false;
, 200);
, true)
您可以根据自己的喜好更改条形码长度和超时速度,但这对我来说非常完美。
【讨论】:
【参考方案8】:尝试了所有解决方案,但没有按预期工作。我找到了非常简单的解决方案 onscan.js 我有使用 angular 8 的应用程序。
非常简单且很好的实现。
对于 angular 8,我按照以下步骤操作:
1.npm install onscan.js --save
2.打开angular.json,在脚本数组中添加一个条目为“node_modules/onscan.js/onscan.min.js”
3.在组件类中,实现接口AfterViewInit
declare var onscan:any;
ngAfterViewInit(): void
//Put focus to textbox and press scanner button
onScan.attachTo(document,
suffixKeyCodes: [13], // enter-key expected at the end of a scan
reactToPaste: true, // Compatibility to built-in scanners in paste-mode (as opposed to keyboard-mode)
onScan: function (sCode, iQty) // Alternative to document.addEventListener('scan')
console.log('Scanned: ' + iQty + 'x ' + sCode);
,
);
最好的办法是扫描文本出现在焦点文本框元素中
希望对您有所帮助。
【讨论】:
适用于 Angular 应用程序,需要处理的事情很少,但可以工作! 二维码扫描设备怎么样?【参考方案9】:我刚刚开始开发一个处理条形码扫描和信用卡扫描的插件(基于 jQuery):
https://github.com/ericuldall/jquery-pos
简单实现:
$(function()
$(document).pos();
$(document).on('scan.pos.barcode', function(event)
var barcode = event.code;
//handle your code here....
);
);
到目前为止,此插件仅使用一种类型的扫描仪和仅包含数字的代码进行了测试,但如果您有其他无法使用它的要求,我很乐意根据您的需要对其进行调整。请查看 github 页面并试一试。鼓励贡献。
E
【讨论】:
【参考方案10】:var txt = "";
function selectBarcode()
if (txt != $("#focus").val())
setTimeout('use_rfid()', 1000);
txt = $("#focus").val();
$("#focus").select();
setTimeout('selectBarcode()', 1000);
$(document).ready(function ()
setTimeout(selectBarcode(),1000);
);
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input type="text" name="tag" id="focus" placeholder="Use handheld RFID scanner">
【讨论】:
以上是关于Javascript:如何最好地读取手持条码扫描仪?的主要内容,如果未能解决你的问题,请参考以下文章