zoukankan      html  css  js  c++  java
  • 国外牛人写的检测条码枪输入的js

    /*
     * 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<oIgnoredObject.length; 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<oOptions.minLength):
                    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();
                    }
                });



  • 相关阅读:
    Knime 使用 初探
    MySql可视化工具MySQL Workbench使用教程
    MySQL导入sql 文件的5大步骤
    Import MySQL Dumpfile, SQL Datafile Into My Database
    导入已有的vmdk文件,发现网络无法连通
    VirtualBox镜像复制载入
    对自己说的话
    linux遇见的问题
    vbox下安装 linux 64 bit出现“kernel requires an x86_64 cpu
    Servlet 3 HttpServletRequest HttpServletResponse 验证码图片 form表单
  • 原文地址:https://www.cnblogs.com/nirvanan/p/11955906.html
Copyright © 2011-2022 走看看