js 条码枪扫描_国外牛人写的检测条码枪输入的js

onScan.js 是一个 JavaScript 库,用于处理硬件条形码扫描器的扫描事件。它支持多种回调功能,如成功扫描、扫描错误、按键处理等,并允许配置扫描按钮、最小长度等参数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*

* onScan.js - scan-events for hardware barcodes scanners in javascript

*/

var onScan = {

attachTo: function(oDomElement, oOptions) {

if(oDomElement.scannerDetectionData != undefined){

throw new Error("onScan.js is already initialized for DOM element " + oDomElement);

}

var oDefaults = {

onScan: function(sScanned, iQty){}, // Callback after detection of a successfull scanning:  function(){sScancode, iCount)}()

onScanError: function(oDebug){}, // Callback after detection of a unsuccessfull scanning (scanned string in parameter)

onKeyProcess: function(sChar, oEvent){}, // Callback after receiving and processing a char (scanned char in parameter)

onKeyDetect: function(iKeyCode, oEvent){}, // Callback after detecting a keyDown (key char in parameter) - in contrast to onKeyProcess, this fires for non-character keys like tab, arrows, etc. too!

onPaste: function(sPasted, oEvent){}, // Callback after receiving a value on paste, no matter if it is a valid code or not

keyCodeMapper: function(oEvent){return String.fromCharCode(oEvent.which)}, // Custom function to decode a keydown event into a character. Must return decoded character or NULL if the given event should not be processed.

onScanButtonLongPress: function(){}, // Callback after detection of a successfull scan while the scan button was pressed and held down

scanButtonKeyCode:false, // Key code of the scanner hardware button (if the scanner button a acts as a key itself)

scanButtonLongPressTime:500, // How long (ms) the hardware button should be pressed, until a callback gets executed

timeBeforeScanTest:100, // Wait duration (ms) after keypress event to check if scanning is finished

avgTimeByChar:30, // Average time (ms) between 2 chars. Used to do difference between keyboard typing and scanning

minLength:6, // Minimum length for a scanning

suffixKeyCodes:[9,13], // Chars to remove and means end of scanning

prefixKeyCodes:[], // Chars to remove and means start of scanning

ignoreIfFocusOn:false, // do not handle scans if the currently focused element matches this selector or object

stopPropagation:false, // Stop immediate propagation on keypress event

preventDefault:false, // Prevent default action on keypress event

reactToKeydown:true, // look for scan input in keyboard events

reactToPaste:false, // look for scan input in paste events

singleScanQty: 1 // Quantity of Items put out to onScan in a single scan

}

oOptions = this._mergeOptions(oDefaults, oOptions);

// initializing options and variables on DomElement

oDomElement.scannerDetectionData = {

options: oOptions,

vars:{

firstCharTime: 0,

lastCharTime: 0,

stringWriting: '',

callIsScanner: false,

testTimer: false,

longPressTimeStart: 0,

longPressed: false

}

};

// initializing handlers (based on settings)

if (oOptions.reactToPaste === true){

oDomElement.addEventListener("paste", this._handlePaste);

}

if (oOptions.scanButtonKeyCode !== false){

oDomElement.addEventListener("keyup", this._handleKeyUp);

}

if (oOptions.reactToKeydown === true || oOptions.scanButtonKeyCode !== false){

oDomElement.addEventListener("keydown", this._handleKeyDown);

}

},

detachFrom: function(oDomElement) {

// detaching all used events

if (oDomElement.scannerDetectionData.options.reactToPaste){

oDomElement.removeEventListener("paste", this._handlePaste);

}

if (oDomElement.scannerDetectionData.options.scanButtonKeyCode !== false){

oDomElement.removeEventListener("keyup", this._handleKeyUp);

}

oDomElement.removeEventListener("keydown", this._handleKeyDown);

// clearing data off DomElement

oDomElement.scannerDetectionData = undefined;

},

getOptions: function(oDomElement){

return oDomElement.scannerDetectionData.options;

},

setOptions: function(oDomElement, oOptions){

// check if some handlers need to be changed based on possible option changes

switch (oDomElement.scannerDetectionData.options.reactToPaste){

case true:

if (oOptions.reactToPaste === false){

oDomElement.removeEventListener("paste", this._handlePaste);

}

break;

case false:

if (oOptions.reactToPaste === true){

oDomElement.addEventListener("paste", this._handlePaste);

}

break;

}

switch (oDomElement.scannerDetectionData.options.scanButtonKeyCode){

case false:

if (oOptions.scanButtonKeyCode !== false){

oDomElement.addEventListener("keyup", this._handleKeyUp);

}

break;

default:

if (oOptions.scanButtonKeyCode === false){

oDomElement.removeEventListener("keyup", this._handleKeyUp);

}

break;

}

// merge old and new options

oDomElement.scannerDetectionData.options = this._mergeOptions(oDomElement.scannerDetectionData.options, oOptions);

// reinitiallize

this._reinitialize(oDomElement);

},

simulate: function(oDomElement, sTestString){

var oVars = oDomElement['scannerDetectionData'].vars;

oVars.firstCharTime = 0;

oVars.lastCharTime = 0;

oVars.stringWriting = sTestString;

this._validateScanCode(oDomElement);

return this;

},

_reinitialize: function(oDomElement){

var oVars = oDomElement['scannerDetectionData'].vars;

oVars.firstCharTime = 0;

oVars.stringWriting = '';

},

_isFocusOnIgnoredElement: function(oDomElement){

oIgnoredObject = oDomElement['scannerDetectionData'].options.ignoreIfFocusOn;

if(!oIgnoredObject){

return false;

}

var oFocused = document.activeElement;

// checks if ignored element is an array, and if so it checks if one of the elements of it is an active one

if (Array.isArray(oIgnoredObject)){

for(var i=0; i

if(Object.is(oFocused, oIgnoredObject[i]) || Object.is(oFocused, document.getElementById(oIgnoredObject[i]))){

return true;

}

}

// if the option consists of an single element, it only checks this one

} else if (Object.is(oFocused, oIgnoredObject) || Object.is(oFocused, document.getElementById(oIgnoredObject))){

return true;

}

// if the active element is not listed in the ignoreIfFocusOn option, return false

return false;

},

_validateScanCode: function(oDomElement){

var oScannerData = oDomElement['scannerDetectionData'];

var oOptions = oScannerData.options;

var iSingleScanQty = oScannerData.options.singleScanQty

var sScanCode = oScannerData.vars.stringWriting;

var iFirstCharTime = oScannerData.vars.firstCharTime;

var iLastCharTime = oScannerData.vars.lastCharTime;

switch(true){

// detect codes that are too short

case (sScanCode.length

var oScanError = {

message: "Receieved code is shorter then minimal length"

};

break;

// detect codes that were entered too slow

case ((iLastCharTime - iFirstCharTime) > (sScanCode.length * oOptions.avgTimeByChar)):

var oScanError = {

message: "Receieved code was not entered in time"

};

break;

// if a code was not filtered out earlier it is valid

default:

oOptions.onScan.call(oDomElement, sScanCode, iSingleScanQty);

var oEvent = new CustomEvent(

'scan',

{

detail: {

scanCode: sScanCode,

qty: iSingleScanQty

}

}

);

oDomElement.dispatchEvent(oEvent);

onScan._reinitialize(oDomElement);

return true;

}

// If an error occurred (otherwise the method would return earlier) create an object for errordetection

oScanError.scanCode = sScanCode;

oScanError.scanDuration = iLastCharTime - iFirstCharTime;

oScanError.avgTimeByChar = oOptions.avgTimeByChar;

oScanError.minLength = oOptions.minLength;

oOptions.onScanError.call(oDomElement, oScanError);

var oEvent = new CustomEvent(

'scanError',

oScanError

);

oDomElement.dispatchEvent(oEvent);

onScan._reinitialize(oDomElement);

return false;

},

_mergeOptions: function(oDefaults, oOptions){

var oExtended = {};

var prop;

for (prop in oDefaults){

if (Object.prototype.hasOwnProperty.call(oDefaults, prop)){

oExtended[prop] = oDefaults[prop];

}

}

for (prop in oOptions){

if (Object.prototype.hasOwnProperty.call(oOptions, prop)){

oExtended[prop] = oOptions[prop];

}

}

return oExtended;

},

_getNormalizedKeyNum: function(e){

var iKeyCode;

if(window.event) { // IE

iKeyCode = e.keyCode;

} else if(e.which){ // Netscape/Firefox/Opera

iKeyCode = e.which;

}

return iKeyCode;

},

_handleKeyDown: function(e){

// overwrite the which value of the event with keycode for cross platform compatibility

e.which = onScan._getNormalizedKeyNum(e);

var iKeyCode = e.which;

var oOptions = this['scannerDetectionData'].options;

var oVars = this['scannerDetectionData'].vars;

oOptions.onKeyDetect.call(this, e.which, e);

if (onScan._isFocusOnIgnoredElement(this)){

return;

}

// If it's just the button of the scanner, ignore it and wait for the real input

if(oOptions.scanButtonKeyCode !== false && iKeyCode==oOptions.scanButtonKeyCode) {

// if the button was first pressed, start a timeout for the callback, which gets interrupted if the scanbutton gets released

if (!oVars.longPressed){

oVars.longPressTimer = setTimeout( oOptions.onScanButtonLongPress, oOptions.scanButtonLongPressTime, this);

oVars.longPressed = true;

}

return;

}

if(oOptions.stopPropagation){

e.stopImmediatePropagation();

}

if(oOptions.preventDefault){

e.preventDefault();

}

switch(true){

// If it's not the first character and we encounter a terminating character, trigger scan process

case (oVars.firstCharTime && oOptions.suffixKeyCodes.indexOf(iKeyCode)!==-1):

e.preventDefault();

e.stopImmediatePropagation();

this['scannerDetectionData'].vars.callIsScanner=true;

break;

// If it's the first character and we encountered one of the starting characters, don't process the scan

case (!oVars.firstCharTime && oOptions.prefixKeyCodes.indexOf(iKeyCode)!==-1):

e.preventDefault();

e.stopImmediatePropagation();

oVars.callIsScanner=false;

break;

// Otherwise, just add the character to the scan string we're building

default:

var character = oOptions.keyCodeMapper.call(this, e);

if (character === null){

return;

}

oVars.stringWriting += character;

oVars.callIsScanner=false;

break;

}

if(!oVars.firstCharTime){

oVars.firstCharTime=Date.now();

}

oVars.lastCharTime=Date.now();

if(oVars.testTimer){

clearTimeout(oVars.testTimer);

}

if(oVars.callIsScanner){

onScan._validateScanCode(this);

oVars.testTimer=false;

} else {

oVars.testTimer=setTimeout(onScan._validateScanCode, oOptions.timeBeforeScanTest, this);

}

oOptions.onKeyProcess.call(this, character, e);

},

_handlePaste: function(e){

// if the focus is on an ignored element, abort

if (onScan._isFocusOnIgnoredElement(this)){

return;

}

e.preventDefault();

var sPasteString = (event.clipboardData || window.clipboardData).getData('text');

this.scannerDetectionData.options.onPaste.call(this, sPasteString, event);

var oVars = this.scannerDetectionData.vars;

oVars.firstCharTime = 0;

oVars.lastCharTime = 0;

oVars.stringWriting = sPasteString;

// validate the string

onScan._validateScanCode(this);

},

_handleKeyUp: function(e){

// if the focus is on an ignored element, abort

if (onScan._isFocusOnIgnoredElement(this)){

return;

}

var iKeyCode = onScan._getNormalizedKeyNum(e);

// if hardware key is not being pressed anymore stop the timeout and reset

if (iKeyCode == this.scannerDetectionData.options.scanButtonKeyCode){

clearTimeout(this.scannerDetectionData.vars.longPressTimer);

this.scannerDetectionData.vars.longPressed = false;

}

}

};

================================

使用方法:

var $OtherSideNo = $("#OtherSideNo");

onScan.attachTo($OtherSideNo[0], {

suffixKeyCodes: [13], // 扫描结束时需要输入回车键

reactToKeydown: true,//对按键作出反应

reactToPaste: true, // 与粘贴模式(与键盘模式相对)的内置扫描仪兼容

onScan: function (sCode, iQty) { //替代document.addEventListener('scan')

console.log('Scanned: ' + iQty + 'x ' + sCode);

$OtherSideNo.change();

$('#CartonNo').focus();

},

onKeyDetect: function (iKeyCode) { //输出所有可能相关的按键事件-非常适合调试!

console.log('Pressed: ' + iKeyCode);

},

//禁止粘贴

onPaste: function (sPasted, oEvent) {

$OtherSideNo.val('');

$OtherSideNo.focus();

},

//扫描错误(用来检测是否键盘输入),禁止键盘输入

onScanError:function(oDebug) {

$OtherSideNo.val('');

$OtherSideNo.focus();

}

});

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值