我如何以编程方式检测文本输入何时通过键盘输入填充以及何时由条形码扫描仪自动填充?
检测输入框何时由键盘填充,何时由条码扫描仪填充。
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);
}
};
改编上面超级有用的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
});
})($);
好吧,条形码不会触发任何关键事件,因此您可以执行以下操作:
$('#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');
}
}
});
根据您想要评估的时间,您可能不想在更改时而是在提交时进行此检查,或者其他任何情况。
您可以尝试以下示例,使用 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'/>
对于 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 上测试