Javascript:如何最好地阅读手持式条形码扫描仪?

时间:2014-02-07 16:57:16

标签: javascript jquery ajax angularjs barcode-scanner

我希望能够通过手持式扫描仪扫描条形码并使用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>");
});
  • 任何想法(框架,插件,片段)?
  • 任何条形码扫描仪(硬件)推荐?

提前致谢!

我发现了thisthis个好问题,但我想了解有关处理的更多信息。在我的情况下,仅仅关注textarea可能还不够。

10 个答案:

答案 0 :(得分:22)

您的伪代码无法正常工作,因为您无权访问扫描程序以捕获scanButtonDown等事件。您唯一的选择是HID扫描仪,其行为与键盘完全相同。要区分扫描仪输入和键盘输入,您有两种选择:基于定时器或基于前缀。

<强>基于定时器

扫描仪可能比使用键盘(明智地)更快地输入字符。计算接收击键的速度,并将快速输入缓冲到变量中以传递给getProductsId函数。 @Vitall写了一个reusable jQuery solution for catching barcode scanner input,你只需要捕获onbarcodescanned事件。

<强>前缀基于

大多数扫描仪都可以配置为所有扫描数据的前缀。您可以使用前缀开始拦截所有输入,一旦您获得了条形码,就可以停止拦截输入。

完全披露:我是Socket Mobile,Inc。的顾问,负责制作手持式扫描仪。

答案 1 :(得分:6)

经过大量研究和测试后,对我来说最有效的方法是从条形码扫描仪捕获输入而不关注表单输入。收听#section1keydown事件。

textInput事件就像textInput事件一样。它有完整的条形码数据。在我的情况下,我正在寻找UPC条形码。 paste阻止条形码数据插入表单输入:

e.preventDefault()

我在Android 4.4和7.0上使用CipherLab红外扫描仪对此进行了测试。

收听document.addEventListener('textInput', function (e){ if(e.data.length >= 6){ console.log('IR scan textInput', e.data); e.preventDefault(); } }); 事件的示例。在我的情况下,我能够假设只要表格输入没有聚焦,用户就会扫描条形码。

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

在此处找到此监控技巧:How do you log all events fired by an element in jQuery?

答案 2 :(得分:4)

好的,所以这就是我的表现。我设置扫描仪,添加前缀(在我的情况下,我使用Ctrl + 2或ascii代码002(控制代码),因此无法通过键盘轻松输入)和一个ENTER,(随意如果条形码数据可能包含输入,则在每次条形码扫描后将其更改为使用Ctrl + 3或ascii代码003。在jQuery中,我捕获了按键事件,并查找前缀。然后,我将所有内容捕获到一个字符串中,然后触发一个自定义事件,我的应用程序可以监听。因为我正在阻止按键事件,所以用户可以在文本字段中,并扫描条形码,这可以触发事件而不会影响他们正在做的任何事情。

此外,每个条形码都有一个我们使用的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);
    }
});

答案 3 :(得分:2)

  

条形码扫描仪几乎像键盘一样工作。

这取决于型号。我使用的每一个都像键盘一样工作(至少就计算机而言)

  

它输出扫描/翻译(条形码 - >数字)数据原始(右?)。

输出密码。

$(document).on("scanButtonDown"

您可能需要keypress,而不是scanButtonDown

查看事件对象以确定按下的“键”。

要确定扫描整个代码的时间,您可能会收到“数据结束”键(可能是空格或返回),或者您可能只需要计算输入的字符数。

答案 4 :(得分:1)

我刚刚开始处理一个处理条形码扫描和信用卡扫描的插件(基于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页面并给它一个旋转。鼓励捐款。

电子

答案 5 :(得分:1)

&#13;
&#13;
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);       
});
&#13;
<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">
&#13;
&#13;
&#13;

答案 6 :(得分:1)

我来不晚,但是我根据这里的一些答案进行了解决。

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

答案 7 :(得分:1)

如果您使用的是PosX扫描仪之一或任何其他能够在字符开头添加特殊符号的扫描仪,则这是Hanz Herdel给出的答案的扩展。在这种情况下,波浪号(〜)符号:

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 :(得分:1)

这里工作正常。
输入没有焦点输入没有焦点

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)
}

HTML

<input type="text" id="scanner" placeholder="scanner">

答案 9 :(得分:0)

尝试了所有解决方案,但没有按预期工作。我找到了非常简单的解决方案 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);
      },
    });
  }

最好的事情是扫描文本出现在焦点文本框元素中

希望对您有所帮助。