Javascript 检测输入框何时由键盘填充,何时由条码扫描仪填充。
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11290898/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Detect when input box filled by keyboard and when by barcode scanner.
提问by MyTitle
How I can programmatically detect when text input filled by typing on keyboard and when it filled automatically by bar-code scanner?
我如何以编程方式检测文本输入何时通过键盘输入填充以及何时由条形码扫描仪自动填充?
采纳答案by Utkanos
Well a barcode won't fire any key events so you could do something like:
好吧,条形码不会触发任何关键事件,因此您可以执行以下操作:
$('#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');
}
}
});
Depending on when you want to evaluate this, you may want to do this check not on change but on submit, or whatever.
根据您想要评估的时间,您可能不想在更改时而是在提交时进行此检查,或者其他任何情况。
回答by Vitall
I wrote this answer, because my Barcode Scanner Motorola LS1203 generated keypress event, so I can't use Utkanos's solution.
我写了这个答案,因为我的条码扫描仪摩托罗拉 LS1203 生成了按键事件,所以我不能使用 Utkanos 的解决方案。
My solution is:
我的解决办法是:
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);
}
};
回答by dextermini
you can try following example, using jQuery plugin https://plugins.jquery.com/scannerdetection/
您可以尝试以下示例,使用 jQuery 插件https://plugins.jquery.com/scannerdetection/
Its highly configurable, time based scanner detector. It can be used as solution for prefix/postfix based, time based barcode scanner.
其高度可配置的基于时间的扫描仪检测器。它可以用作基于前缀/后缀、基于时间的条码扫描器的解决方案。
Tutorial for usage and best practices, as well discussed about various Barcode Scanner Models and how to deal with it. http://a.kabachnik.info/jquery-scannerdetection-tutorial.html
使用和最佳实践教程,以及有关各种条码扫描仪模型及其处理方法的讨论。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'/>
回答by Spence7
Adapted the super useful Vitall answer aboveto utilize an IIFE instead of prototyping, in case anyone just seeing this now is into that.
改编上面超级有用的Vitall 答案以使用 IIFE 而不是原型设计,以防任何人现在看到这个。
This also uses the 'keypress' event instead of keyup, which allowed me to reliably use KeyboardEvent.key, since KeyboardEvent.which is deprecated now. I found this to work for barcode scanning as well as magnetic-strip card swipes.
这也使用 'keypress' 事件而不是 keyup,这使我能够可靠地使用 KeyboardEvent.key,因为 KeyboardEvent.which 现在已弃用。我发现这适用于条码扫描以及磁条卡刷卡。
In my experience, handling card swipes with keyup caused me to do extra work handling 'Shift' keycodes e.g. a Shift code would be followed by the code representing '/', with the intended character being '?'. Using 'keypress' solved this as well.
根据我的经验,使用 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
});
})($);
回答by MisieQQQ
For ES6 2019 version of Vitall answer.
对于 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)
}
}
Can be used with react hooks like so:
可以像这样与 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>
}
I use mitt from npm for events, but you can use whatever you prefer ;)
我使用 npm 中的 mitt 进行事件,但您可以使用任何您喜欢的 ;)
Tested on Zebra DS4208
在 Zebra DS4208 上测试
回答by Mhastrich
The solution from Vitall only works fine if you already hit at least one key. If you don't the first character will be ignored (if(this._timeoutHandler) returns false and the char will not be appended).
Vitall 的解决方案仅在您已经按下至少一个键时才能正常工作。如果不这样做,第一个字符将被忽略(if(this._timeoutHandler) 返回 false 并且不会附加字符)。
If you want to begin scanning immediately you can use the following code:
如果您想立即开始扫描,您可以使用以下代码:
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);
}
};
回答by Tobia
If you can set a prefix to your barcode scanner I suggests this (I changed a bit the Vitall code):
如果您可以为条形码扫描仪设置前缀,我建议这样做(我稍微更改了 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;
}
};
If you need you customize timeout, suffix, prefix, min/max ascii code readed:
如果您需要自定义超时、后缀、前缀、最小/最大 ascii 代码读取:
new BarcodeScanner({timeout: 600, prefixKeyCode: 36, suffixKeyCode: 13, minKeyCode: 32, maxKeyCode: 126});
I also added the isShiftPrefix
option to use for example the $
char as prefix with these options: new BarcodeScanner({prefixKeyCode: 52, isShiftPrefix: true});
我还添加了isShiftPrefix
使用例如$
char 作为前缀的选项与这些选项:new BarcodeScanner({prefixKeyCode: 52, isShiftPrefix: true});
This is a fiddle: https://jsfiddle.net/xmt76ca5/
这是一个小提琴:https: //jsfiddle.net/xmt76ca5/
回答by Sudip Pal
You can use a "onkeyup" event on that input box. If the event has triggered then you can called it "Input from Keyboard".
您可以在该输入框上使用“onkeyup”事件。如果事件已触发,则您可以将其称为“从键盘输入”。
回答by mallesh mk
$(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'/>
回答by Juan Carlos
Hi I have and alternative solution for evaluate a result of the bar code scanner without use of jQuery, first you need and input text that have a focus the moment that the barcode scanner is works
嗨,我有一个替代解决方案来评估条形码扫描仪的结果而不使用 jQuery,首先您需要并输入在条形码扫描仪工作时具有焦点的文本
<input id="input_resultado" type="text" />
The code in JavaScript is:
JavaScript 中的代码是:
var elmInputScan = document.getElementById('input_resultado');
elmInputScan.addEventListener('keypress', function (e){
clearInterval( timer_response );
timer_response = setTimeout( "onInputChange()", 10);
});
When the barcode scanner input the text call serveral times to the keypress event, but only I interested to the final result, for this reason I use the timer. That's all, you can process the value into the onInputChange function.
当条码扫描器输入文本时,会向按键事件调用几次,但只有我对最终结果感兴趣,因此我使用计时器。就是这样,您可以将值处理到 onInputChange 函数中。
function onInputChange() {
console.log( document.getElementById('input_resultado').value );
}