我希望能够通过手持式扫描仪扫描条形码,并使用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>");
});
提前致谢!
我发现this和this很好的问题,但我想获得有关处理的更多信息。在我的案例中,仅仅关注一个textarea可能是不够的。
您的伪代码无效,因为您无法访问扫描程序来捕获scanButtonDown
等事件。您唯一的选择是HID扫描仪,其行为与键盘完全相同。要区分扫描仪输入和键盘输入,您有两种选择:基于定时器或基于前缀。
基于定时器
扫描仪可能比使用键盘(明智地)更快地输入字符。计算接收击键的速度,并将快速输入缓冲到变量中以传递给getProductsId
函数。 @Vitall写了一个reusable jQuery solution for catching barcode scanner input,你只需要捕获onbarcodescanned事件。
前缀为基础
大多数扫描仪可以配置为所有扫描数据的前缀。您可以使用前缀开始拦截所有输入,一旦获得条形码,就可以停止拦截输入。
完全披露:我是Socket Mobile,Inc。的顾问,负责制造手持式扫描仪。
经过大量的研究和测试,对我来说最有效的方法是从条形码扫描仪捕获输入,而无需关注表单输入。听听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();
}
});
我已经在Android 4.4和7.0上使用CipherLab IR扫描仪对此进行了测试。
收听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);
}
}
}
当然,您可以在e.keyCode === 13
事件侦听器中侦听keydown
,而不是检查字符串的长度来确定扫描。
并非所有红外扫描仪都会触发textInput
事件。如果您的设备没有,那么您可以检查它是否发出类似的东西:
monitorEvents(document.body);
在这里找到了这个监控技巧:How do you log all events fired by an element in jQuery?
好的,所以这就是我做的。我设置扫描仪,添加前缀(在我的情况下,我使用Ctrl + 2或ascii代码002(控制代码),因此无法通过键盘轻松输入)和一个ENTER,(随意如果条形码数据可能包含输入,则在每次条形码扫描后将其更改为使用Ctrl + 3或ascii代码003。在jQuery中,我捕获了按键事件,并查找前缀。然后,我将所有内容捕获到一个字符串中,然后触发一个自定义事件,我的应用程序可以监听。因为我正在阻止按键事件,所以用户可以在文本字段中,并扫描条形码,这可以触发事件而不会影响他们正在做的任何事情。
此外,每个条形码都有一个我们使用的1位前缀,用于识别扫描的条形码类型。例子:
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);
}
});
条形码扫描仪几乎像键盘一样工作。
这取决于模型。我使用的每一个都像键盘一样工作(至少就计算机而言)
它输出扫描/翻译(条形码 - >数字)数据原始(对吗?)。
它输出密钥代码。
$(document).on("scanButtonDown"
你可能想要keypress
,而不是scanButtonDown
。
查看事件对象以确定按下的“键”。
要确定扫描整个代码的时间,您可能会收到“数据结束”键(可能是空格或返回),或者您可能只需要计算输入的字符数。
我刚刚开始处理一个处理条形码扫描和信用卡扫描的插件(基于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页面并给它一个旋转。鼓励捐款。
和
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">
我迟到了但是我在这里解决了一些问题。
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