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】:

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

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)

html

<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:如何最好地读取手持条码扫描仪?的主要内容,如果未能解决你的问题,请参考以下文章

东集pdaQ7 怎么扫描

使用 Kivy 读取条码扫描器

如何使用不模拟键盘的条码扫描仪读取条码?

霍尼韦尔1900扫描枪如何正确扫描显示屏?

关于Android手持机,扫描枪的问题,怎么获取扫描的信息

如何添加 Javascript 侦听器以捕获从蓝牙条码扫描器到 iPad 的输入?