Обнаруживать, когда поле ввода заполняется клавиатурой, а когда - с помощью сканера штрих-кода.

Как я могу программно обнаруживать, когда текстовый ввод заполнялся путем ввода на клавиатуре и когда он автоматически заполнялся сканером штрих-кода?

Ответ 1

Ну, штрих-код не будет запускать какие-либо ключевые события, чтобы вы могли сделать что-то вроде:

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

В зависимости от того, когда вы хотите оценить это, вы можете выполнить эту проверку не при изменении, а в submit или любом другом.

Ответ 2

Я написал этот ответ, потому что мой сканер штрих-кода 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);
    }
};

Ответ 3

Вы можете попробовать следующий пример, используя плагин 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'/>

Ответ 4

Адаптировал супер полезный ответ Vitall выше, чтобы использовать IIFE вместо прототипирования, на тот случай, если кто-то только что увидит это сейчас.

Это также использует событие "нажатие клавиши" вместо keyup, что позволило мне надежно использовать KeyboardEvent.key, поскольку KeyboardEvent.which устарела. Я нашел, что это работает для сканирования штрих-кода, а также считывания карт с магнитной полосой.

По моему опыту, обработка карточных свипов с помощью keyup заставила меня выполнить дополнительную работу по обработке кодов клавиш "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
    });
})($);

Ответ 5

Если вы можете установить префикс для вашего сканера штрих-кода, я предлагаю это (я немного изменил код 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;
    }
};

Если вам нужно настроить время ожидания, суффикс, префикс, минимальный/максимальный код ascii:

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

Я также добавил параметр isShiftPrefix чтобы использовать, например, префикс $ char в качестве следующих параметров: new BarcodeScanner({prefixKeyCode: 52, isShiftPrefix: true});

Это скрипка: https://jsfiddle.net/xmt76ca5/

Ответ 6

В этом поле ввода вы можете использовать событие onkeyup. Если событие срабатывает, вы можете вызвать его "Вход с клавиатуры".

Ответ 7

Решение Vitall работает отлично, если вы уже нажали хотя бы на один ключ. Если вы не первый символ будет проигнорирован (если (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);
	}
};

Ответ 8

$(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'/>

Ответ 9

Привет, у меня есть и альтернативное решение для оценки результата сканера штрих-кода без использования jQuery, сначала вам нужно и введите текст, который имеет фокус в момент работы сканера штрих-кода

<input id="input_resultado" type="text" />

Код в JavaScript:

var elmInputScan = document.getElementById('input_resultado');           

elmInputScan.addEventListener('keypress', function (e){        
  clearInterval( timer_response );    
  timer_response = setTimeout( "onInputChange()", 10);
});    

Когда сканер штрих-кода вводит текстовые вызовы несколько раз в событие нажатия клавиши, но только я заинтересован в конечном результате, по этой причине я использую таймер. Это все, вы можете обработать значение в функцию onInputChange.

function onInputChange() {    
  console.log( document.getElementById('input_resultado').value );
}

Ответ 10

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