web-dev-qa-db-ja.com

入力ボックスがキーボードで満たされたとき、およびバーコードスキャナーでいつ検出されたかを検出します。

キーボードで入力することでテキスト入力が満たされたときと、バーコードスキャナーで自動的に入力されたときをプログラムで検出する方法を教えてください。

23
MyTitle

バーコードはキーイベントを発生させないため、次のようなことができます。

$('#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');
        }
    }
});

これを評価するタイミングに応じて、変更時ではなく、送信時などにこのチェックを行うことができます。

7
Utkanos

バーコードスキャナーの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);
    }
};
27
Vitall

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'/>
7
dextermini

非常に便利な 上記のVitallの回答 を採用して、プロトタイプを作成する代わりにIIFEを使用するようにしました。

これはまた、keyupの代わりに 'keypress'イベントを使用します。これにより、KeyboardEvent。は非推奨になっているため、KeyboardEvent.keyを確実に使用できます。これは、バーコードスキャンや磁気ストリップカードスワイプでも機能することがわかりました。

私の経験では、キーアップでカードスワイプを処理すると、「Shift」キーコードを処理する余分な作業が必要になりました。 Shiftコードの後に​​は、「/」を表すコードが続き、目的の文字は「?」になります。 「キープレス」を使用してこれも解決しました。

(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
    });
})($);
4
Spence7

バーコードスキャナーにプレフィックスを設定できる場合は、これをお勧めします(Vitallコードを少し変更しました):

_var BarcodeScanner = function(options) {
     this.initialize.call(this, options);
};
BarcodeScanner.prototype = {
    initialize: function(options) {
       $.extend(this._options,options);
       if(this._options.debug) console.log("BarcodeScanner: Initializing");
       $(this._options.eventObj).on({
          keydown: $.proxy(this._keydown, this),
       });
    },
    destroy: function() {
        $(this._options.eventObj).off("keyup",null,this._keyup);
        $(this._options.eventObj).off("keydown",null,this._keydown);
    },
    fire: function(str){
        if(this._options.debug) console.log("BarcodeScanner: Firing barcode event with string: "+str);
        $(this._options.fireObj).trigger('barcode',[str]);
    },
    isReading: function(){
        return this._isReading;
    },
    checkEvent: function(e){
        return this._isReading || (this._options.isShiftPrefix?e.shiftKey:!e.shiftKey) && e.which==this._options.prefixCode;
    },
    _options: {timeout: 600, prefixCode: 36, suffixCode: 13, minCode: 32, maxCode: 126, isShiftPrefix: false, debug: false, eventObj: document, fireObj: document},
    _isReading: false,
    _timeoutHandler: false,
    _inputString: '',
    _keydown: function (e) {
        if(this._input.call(this,e))
            return false;
    },
    _input: function (e) {
        if(this._isReading){
            if(e.which==this._options.suffixCode){
                //read end
                if(this._options.debug) console.log("BarcodeScanner: Read END");
                if (this._timeoutHandler) 
                    clearTimeout(this._timeoutHandler);
                this._isReading=false;
                this.fire.call(this,this._inputString);
                this._inputString='';
            }else{
                //char reading
                if(this._options.debug) console.log("BarcodeScanner: Char reading "+(e.which));
                if(e.which>=this._options.minCode && e.which<=this._options.maxCode)
                    this._inputString += String.fromCharCode(e.which);
            }
            return true;
        }else{
            if((this._options.isShiftPrefix?e.shiftKey:!e.shiftKey) && e.which==this._options.prefixCode){
                //start reading
                if(this._options.debug) console.log("BarcodeScanner: Start reading");
                this._isReading=true;
                this._timeoutHandler = setTimeout($.proxy(function () {
                    //read timeout
                    if(this._options.debug) console.log("BarcodeScanner: Read timeout");
                    this._inputString='';
                    this._isReading=false;
                    this._timeoutHandler=false;
                }, this), this._options.timeout);
                return true;
            }
        }
        return false;
    }
};
_

必要に応じて、タイムアウト、サフィックス、プレフィックス、最小/最大アスキーコードをカスタマイズします。

_new BarcodeScanner({timeout: 600, prefixKeyCode: 36, suffixKeyCode: 13, minKeyCode: 32, maxKeyCode: 126});
_

また、isShiftPrefixオプションを追加して、たとえば_$_ charをこれらのオプションのプレフィックスとして使用します:new BarcodeScanner({prefixKeyCode: 52, isShiftPrefix: true});

これはフィドルです。 https://jsfiddle.net/xmt76ca5/

2
Tobia

Vitallのソリューションは、少なくとも1つのキーを既に押した場合にのみ正常に機能します。そうしないと、最初の文字は無視されます(if(this._timeoutHandler)はfalseを返し、charは追加されません)。

すぐにスキャンを開始する場合は、次のコードを使用できます。

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);
        }
};
1
Mhastrich

その入力ボックスで「onkeyup」イベントを使用できます。イベントがトリガーされた場合、「キーボードからの入力」と呼ぶことができます。

1
Sudip Pal

VitallのES6 2019バージョンの回答。

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

次のようなリアクションフックで使用できます。

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のミットを使用しますが、好きなものを使用できます;)

Zebra DS4208でテスト済み

0
MisieQQQ
$(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'/>
0
mallesh mk