Javascript:如何最好地读取手持条码扫描器?

IT技术 javascript jquery ajax angularjs barcode-scanner
2021-03-16 13:19:18

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

提前致谢!

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

6个回答

您的伪代码将无法工作,因为您无权访问扫描器来捕获诸如scanButtonDown. 您唯一的选择是 HID 扫描仪,它的行为与键盘完全相同。要将扫描仪输入与键盘输入区分开来,您有两种选择:基于定时器或基于前缀。

基于定时器

扫描仪输入字符的速度可能比用户(明智地)使用键盘输入的速度快得多。计算接收击键的速度并将快速输入缓冲到变量中以传递给您的getProductsId函数。@Vitall 编写了一个可重用的 jQuery 解决方案来捕获条形码扫描仪输入,您只需要捕获 onbarcodescanned 事件。

基于前缀

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

全面披露:我是 Socket Mobile, Inc. 的顾问,该公司制造手持式扫描仪。

有没有办法在最后删除返回/输入?
2021-05-04 13:19:18
@yeouuu 检查您的扫描仪文档。通常有一种方法可以禁用它,但它因扫描仪而异。或者,由于您正在捕获每个键事件,因此您可以preventDefault在每次扫描结束时使用“吞下”返回/输入键
2021-05-08 13:19:18
我知道这是一篇旧帖子,但也想指出 HID 扫描仪也可能在输入的末尾使用返回字符/键。
2021-05-09 13:19:18
我已将基于计时器的解决方案倒入 vanilla-js 包中,效果非常好!npmjs.com/package/@itexerts/barcode-scanner
2021-05-13 13:19:18

经过大量的研究和测试,对我来说最有效的是从条码扫描仪捕获输入而不聚焦表单输入。收听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);
          } 
       }
    });

当然,您可以e.keyCode === 13keydown事件侦听器中侦听,而不是通过检查字符串的长度来确定扫描

并非所有 IR 扫描仪都会触发该textInput事件。如果您的设备没有,那么您可以检查它是否发出类似于以下内容的内容:

monitorEvents(document.body);

在这里找到了这个监控技巧: 如何记录 jQuery 中元素触发的所有事件?

很高兴听到你成功了!仅供参考,您的项目链接末尾有一个额外的“i”。
2021-04-28 13:19:18
我不是; 我在 android 设备上使用网络应用程序清单。我最终弄清楚了如何使用textInput并在此处发布了代码:github.com/kjantzer/backbone-barcode-scanneri 您的评论textInput帮助我找到了正确的方向!
2021-05-07 13:19:18
@KevinJantzer 你在开发 Cordova iOS 应用程序吗?我今天才发现,除非输入被聚焦,否则 iOS 不会触发 Web 视图中的键盘事件。我修改了 Cordova iOS 插件来捕获键盘事件并将它们发送到我的应用程序: github.com/SimpleJoySolutions/cordova.externalkeyboard
2021-05-20 13:19:18
document.addEventListener('textInput'... 为你工作?我只inputs在聚焦时才收到该事件:\
2021-05-21 13:19:18

我有点晚了,但我根据这里的一些答案完成了这项工作。

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
    }
}
当我扫描带有 URL 的 QRCode 时,返回 null。
2021-05-04 13:19:18
如果您正在寻找某些东西,这是可以使用的解决方案。请注意,并非所有扫描仪都一样。对于某些蓝牙/更便宜的扫描仪,200 毫秒的超时可能不够。我建议允许客户调整此设置以满足他们的需求。
2021-05-20 13:19:18

好的,这就是我如何做到的。我设置了扫描仪,添加了一个前缀(在我的例子中,我使用了 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);
    }
});

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

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

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

它输出键码。

$(document).on("scanButtonDown"

你可能想要keypress,不是scanButtonDown

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

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