【问题标题】:Javascript: How to read a hand held barcode scanner best?Javascript:如何最好地读取手持条码扫描仪?
【发布时间】: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)吗?
  • 有什么条码扫描仪(硬件)推荐吗?

提前致谢!

我找到了thisthis 很好的问题,但我想了解有关处理的更多信息。在我的情况下,仅仅关注一个文本区域可能是不够的。

【问题讨论】:

    标签: javascript jquery ajax angularjs barcode-scanner


    【解决方案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">

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2013-10-13
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2020-11-18
                • 2022-11-04
                • 2014-12-11
                • 2021-09-24
                相关资源
                最近更新 更多