如何以编程方式检测何时通过键盘输入填充文本输入以及何时通过条形码扫描器自动填充文本输入?
答案 0 :(得分:25)
我写了这个答案,因为我的条形码扫描仪摩托罗拉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);
}
};
答案 1 :(得分:6)
条形码不会触发任何关键事件,因此您可以执行以下操作:
$('#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');
}
}
});
根据您要对此进行评估的时间,您可能希望执行此检查,而不是在更改时,而是在提交时,或其他任何内容。
答案 2 :(得分:5)
您可以使用jQuery插件https://plugins.jquery.com/scannerdetection/
尝试以下示例高度可配置的基于时间的扫描仪探测器。它可以用作基于时间/后缀的基于时间的条形码扫描器的解决方案。
使用和最佳实践教程,以及各种条形码扫描仪模型以及如何处理它的讨论。 http://a.kabachnik.info/jquery-scannerdetection-tutorial.html
INSERT INTO schema.locations_borrowers (id_borrower, id_location)
SELECT borrowers.id_borrower, locations.id_location FROM borrowers JOIN schema.all_proto
ON borrowers.forename = all_proto.borrower_forename AND borrowers.surname = all_proto.borrower_surname
INNER JOIN locations ON locations.street = all_proto.street AND locations.town = all_proto.town;
$(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');
答案 3 :(得分:4)
对超级有用的Vitall answer above进行了调整,使其可以利用IIFE代替原型,以防万一有人立即看到它。
这也使用了'keypress'事件而不是keyup,这使我能够可靠地使用KeyboardEvent.key,因为现在不推荐使用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 :(得分:2)
如果您可以为条形码扫描仪设置前缀,我建议这样做(我改变了一点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代码readed:
new BarcodeScanner({timeout: 600, prefixKeyCode: 36, suffixKeyCode: 13, minKeyCode: 32, maxKeyCode: 126});
我还添加了isShiftPrefix
选项,例如$
字符作为前缀使用这些选项:new BarcodeScanner({prefixKeyCode: 52, isShiftPrefix: true});
这是一个小提琴:https://jsfiddle.net/xmt76ca5/
答案 5 :(得分:1)
您可以在该输入框中使用“onkeyup”事件。如果事件已触发,则可以将其命名为“从键盘输入”。
答案 6 :(得分:1)
如果你已经击中至少一个键,那么Vitall的解决方案只能正常工作。如果不这样做,第一个字符将被忽略(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);
}
};
答案 7 :(得分:0)
try{
Process su = Runtime.getRuntime().exec("su");
DataOutputStream outputStream = new DataOutputStream(su.getOutputStream());
outputStream.writeBytes("pm uninstall package_name\n");
outputStream.flush();
outputStream.writeBytes("exit\n");
outputStream.flush();
su.waitFor();
}catch(IOException e){
throw new Exception(e);
}catch(InterruptedException e){
throw new Exception(e);
}
$(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');
答案 8 :(得分:0)
您好,我有一个替代解决方案,无需使用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 );
}
答案 9 :(得分:0)
对于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)
}
}
可以与react钩子一起使用,像这样:
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上测试
答案 10 :(得分:0)
document.addEventListener("keypress", function (e) {
if (e.target.tagName !== "INPUT") {
// it's your scanner
}
});
答案 11 :(得分:0)
没有一个解决方案对我有用,因为我不想专注于输入。我希望结果页面(项目详细信息页面)继续监听扫描仪扫描下一个项目。我的扫描仪触发了按键事件,所以这对我来说就像一个魅力。
var inputTemp = '';
var inputTempInterval = setInterval(function() {
// change 5 as minimum length of the scan code
if (inputTemp.length >= 5) {
var detected = inputTemp;
inputTemp = '';
clearInterval(inputTempInterval); // stop listening if you don't need anymore
onScannerTrigger(detected);
} else {
inputTemp = '';
}
}, 100);
$(window).keypress(function(e){
inputTemp += String.fromCharCode(e.which);
});
function onScannerTrigger(scannedCode) {
console.log(scannedCode);
// do your stuff
}
答案 12 :(得分:-1)
我强烈推荐这个js插件https://github.com/axenox/onscan.js 它易于使用,并且可以满足您的需求。