检测输入框何时由键盘填充,何时由条码扫描仪填充。

IT技术 javascript barcode-scanner
2021-02-26 16:55:33

我如何以编程方式检测文本输入何时通过键盘输入填充以及何时由条形码扫描仪自动填充?

6个回答

我写了这个答案,因为我的条码扫描仪 Motorola LS1203 生成了按键事件,所以我不能使用 Utkanos 的解决方案。

我的解决办法是:

var BarcodeScanerEvents = function() {
     this.initialize.apply(this, arguments);
};

BarcodeScanerEvents.prototype = {
    initialize: function() {
       $(document).on({
          keyup: $.proxy(this._keyup, this)
       });
    },
    _timeoutHandler: 0,
    _inputString: '',
    _keyup: function (e) {
        if (this._timeoutHandler) {
            clearTimeout(this._timeoutHandler);
            this._inputString += String.fromCharCode(e.which);
        } 

        this._timeoutHandler = setTimeout($.proxy(function () {
            if (this._inputString.length <= 3) {
                this._inputString = '';
                return;
            }

            $(document).trigger('onbarcodescaned', this._inputString);

            this._inputString = '';

        }, this), 20);
    }
};
@AhmadKarimi,要添加事件侦听器,您只需要在方法上使用 jquery,例如 $(document).on( "onbarcodescaned", function(inputString) { // your code here in inputString should be barcode result });
2021-04-28 16:55:33
Vitall,我不是 JavaScript 人。如果我知道这段代码是如何工作的以及如何在我自己的代码中使用它,我将非常感激。我想为 $(document) 元素放置一个事件侦听器,以便在扫描条形码时随时捕获。
2021-05-15 16:55:33
@AhmadKarimi 我的回答也很旧,请尝试使用代码的改编版本stackoverflow.com/a/56540835/527925
2021-05-18 16:55:33

改编上面超级有用的Vitall 答案以使用 IIFE 而不是原型设计,以防任何人现在看到这个。

这也使用了 'keypress' 事件而不是 keyup,这使我能够可靠地使用 KeyboardEvent.key,因为 KeyboardEvent.which 现在已被弃用。我发现这适用于条码扫描以及磁条卡刷卡。

根据我的经验,使用 keyup 处理刷卡使我需要做额外的工作来处理 'Shift' 键码,例如 Shift 码后跟代表 '/' 的代码,预期字符是 '?'。使用'keypress'也解决了这个问题。

(function($) {
    var _timeoutHandler = 0,
        _inputString = '',
        _onKeypress = function(e) {
            if (_timeoutHandler) {
                clearTimeout(_timeoutHandler);
            }
            _inputString += e.key;

            _timeoutHandler = setTimeout(function () {
                if (_inputString.length <= 3) {
                    _inputString = '';
                    return;
                }
                $(e.target).trigger('altdeviceinput', _inputString);
                _inputString = '';

            }, 20);
        };
    $(document).on({
        keypress: _onKeypress
    });
})($);
谢谢。此外,在我自己的使用中,我注意到一些浏览器(IE、Firefox)将e.key键盘键的值(如退格键)赋予"BACKSPACE"并触发事件。我通过添加解决了这个问题if(e.key.length == 1) _inputString += e.key;
2021-04-23 16:55:33
此外,$(document).trigger(...应该更改为,$(e.target).trigger(...以便事件注册到所需的 DOM 对象。
2021-05-04 16:55:33
这对我有用。为了获得条码值,我必须像这样订阅触发器:$(document).on("altdeviceinput", function (e, barCode) { ...
2021-05-10 16:55:33
想指出的是,此解决方案还修复了@Vitall 的答案所具有的第一个字符缺失错误。
2021-05-12 16:55:33
@khashashin 基本算法是:在按键事件上,如果等待执行,则取消 setTimeout 调用,将按下的键值添加到输入缓冲区,然后调用 setTimeout。如果在 20 毫秒内没有捕获另一个按键,则将调用传递给 setTimeout 的函数。如果输入字符串长度至少为 3 个字符,则该函数将触发事件(这与短超时相结合足以指示扫描)。无论哪种方式,都会刷新输入缓冲区。
2021-05-16 16:55:33

好吧,条形码不会触发任何关键事件,因此您可以执行以下操作:

$('#my_field').on({
    keypress: function() { typed_into = true; },
    change: function() {
        if (typed_into) {
            alert('type');
            typed_into = false; //reset type listener
        } else {
            alert('not type');
        }
    }
});

根据您想要评估的时间,您可能不想在更改时而是在提交时进行此检查,或者其他任何情况。

谢谢。但是我如何检测条形码何时被输入?onCange事件仅在元素失去焦点时上升,但我需要在插入后立即知道插入的值。我可以制作计时器并定期检查文本字段上的值,但我认为这是错误的解决方案。
2021-04-21 16:55:33
我在Android手机条码扫描中尝试过,它只是采取按键事件而不是条码扫描?这是如何为你们工作的。
2021-05-05 16:55:33
当您想要检查输入时,您没有在问题中提到,所以我假设 onChange。是的,我认为计时器可能是唯一的方法,除非条码应用程序在操作页面时触发某种自定义事件。
2021-05-10 16:55:33

您可以尝试以下示例,使用 jQuery 插件https://plugins.jquery.com/scannerdetection/

其高度可配置的基于时间的扫描仪检测器。它可以用作基于前缀/后缀、基于时间的条码扫描器的解决方案。

使用和最佳实践教程,以及有关各种条码扫描仪模型及其处理方法的讨论。http://a.kabachnik.info/jquery-scannerdetection-tutorial.html

$(window).ready(function(){

	//$("#bCode").scannerDetection();

	console.log('all is well');
	
	$(window).scannerDetection();
	$(window).bind('scannerDetectionComplete',function(e,data){
            console.log('complete '+data.string);
            $("#bCode").val(data.string);
        })
        .bind('scannerDetectionError',function(e,data){
            console.log('detection error '+data.string);
        })
        .bind('scannerDetectionReceive',function(e,data){
            console.log('Recieve');
            console.log(data.evt.which);
        })

        //$(window).scannerDetection('success');
<input id='bCode'type='text' value='barcode appears here'/>

谢谢我正在寻找这个。My-barcode Reader-inateck(p6 条码扫描器)
2021-05-01 16:55:33

对于 ES6 2019 版本的 Vitall 答案。

const events = mitt()

class BarcodeScaner {
  initialize = () => {
    document.addEventListener('keypress', this.keyup)
    if (this.timeoutHandler) {
      clearTimeout(this.timeoutHandler)
    }
    this.timeoutHandler = setTimeout(() => {
      this.inputString = ''
    }, 10)
  }

  close = () => {
    document.removeEventListener('keypress', this.keyup)
  }

  timeoutHandler = 0

  inputString = ''

  keyup = (e) => {
    if (this.timeoutHandler) {
      clearTimeout(this.timeoutHandler)
      this.inputString += String.fromCharCode(e.keyCode)
    }

    this.timeoutHandler = setTimeout(() => {
      if (this.inputString.length <= 3) {
        this.inputString = ''
        return
      }
      events.emit('onbarcodescaned', this.inputString)

      this.inputString = ''
    }, 10)
  }
}

可以像这样与 react hooks 一起使用:

const ScanComponent = (props) => {
  const [scanned, setScanned] = useState('')
  useEffect(() => {
    const barcode = new BarcodeScaner()
    barcode.initialize()
    return () => {
      barcode.close()
    }
  }, [])

  useEffect(() => {
    const scanHandler = code => {
      console.log(code)
      setScanned(code)
    }

    events.on('onbarcodescaned', scanHandler)
    return () => {
      events.off('onbarcodescaned', scanHandler)
    }
  }, [/* here put dependencies for your scanHandler ;) */])
  return <div>{scanned}</div>
}

我使用 npm 中的 mitt 进行事件,但您可以使用任何您喜欢的 ;)

在 Zebra DS4208 上测试