• 前端使用扫码枪


    扫码枪

    扫码枪是与键盘功能类似的输入设备,通过扫描条形码,解析条形码编码,随后像键盘一样一个字符一个字符的输入焦点所在位置。


    获取扫码枪输入

    扫码枪输入效果类似键盘,连续扫码不会清空上一个条形码的编码。

    一般会在扫码后默认触发一个Enter键,扫码设备一般也可以设置取消Enter键,具体见设备的说明书。

    扫码枪输入速度很快。

    1.焦点元素获取扫码结果

    焦点元素是指 input,textarea, <el editable />。此类元素在获取扫码枪输入时,有两个关键点:

    1. 保证扫码中途聚焦(且焦点始终在内容结尾)
    2. 每扫一次码,都需要清空上一个条形码的内容。

    antd中的 Input为例:

    此外全局变量应该定义在组件外,或者用ref存起来。

    let typeVal = '';
    let lastTime = 0;
    

    组件如下:

       	
       	const scanRef = useRef();
       	const [scanVal, setScanVal] = useState('');
       	
       	const handlekeyDown = (e) => {
       	        let nextTime = 0;
       	        let keyCode = e.keyCode || e.which || e.charCode;
       	        let shift = e.shiftKey;
       	        nextTime = new Date().getTime();
       	        // console.log('keyUp',keyCode, shift)
       	        if(keyCode == 229){
       	            return
       	        }
       	        //字母上方 数字键0-9 对应键码值 48-57; 数字键盘 数字键0-9 对应键码值 96-105
       	        if ((keyCode >= 48 && keyCode <= 57) || (keyCode >= 96 && keyCode <= 105)) {
       	            let codes = {
       	                '48': 48,
       	                '49': 49,
       	                '50': 50,
       	                '51': 51,
       	                '52': 52,
       	                '53': 53,
       	                '54': 54,
       	                '55': 55,
       	                '56': 56,
       	                '57': 57,
       	                '96': 48,
       	                '97': 49,
       	                '98': 50,
       	                '99': 51,
       	                '100': 52,
       	                '101': 53,
       	                '102': 54,
       	                '103': 55,
       	                '104': 56,
       	                '105': 57,
       	            };
       	            keyCode = codes[keyCode];
       	            nextTime = new Date().getTime();
       	        }
       	
       	        lastTime = nextTime;
       	        if (keyCode == 13) {
       	            let code = typeVal.trim()
       	            setScanVal(code);
       	            typeVal = '';
       	            handlerCode(code)
       	            return;
       	        }
       	        if (keyCode !== 16) {
       	            let val = getValFromKeyCode(keyCode, shift);
       	            if (nextTime && lastTime && nextTime - lastTime > 300) {
       	                typeVal = val;
       	            } else {
       	                typeVal += val;
       	            }
       	        }
       	    };
       	    const getValFromKeyCode = (keyCode, shift) => {
       	        if (keyCode == 189) {
       	            return '-';
       	        }
       	        if (keyCode == 187 || keyCode == 107) {
       	            return '+';
       	        }
       	        if (shift && keyCode == 52) {
       	            return '$';
       	        }
       	        return String.fromCharCode(keyCode);
       	    };
       		
       		const handlerCode = (code) => {
       			//此处为获取到的编码,可以做接口操作
       		}
    
           <Input
       		ref={scanRef}
       		value={scanVal}
       		placeholder="在此处扫码"
       		onKeyUp={handlekeyUp}
       		//聚焦
       		onBlur={() => {
       			scanRef.current.input.focus();
       		}}
       	/>
    
    几个问题:
    1. 监听输入的事件有 onChange, onKeyDown, onKeyUp,经尝试发现 onKeyUp是最合适的。
      原因在于按下回车的时候,也会触发onChange事件。因此,无法排除这次onChange的调用,会造成获取到的编码拼接混乱。

      onKeyDown则是因为:作为输入设备,监听onKeyDown 在输入shift切换大小写(或者中文输入法的情况下),会出现keyCode是229的情况,
      根据229获取内容(String.fromCharCode(229)), 得到的是 å这样的符号,因此会乱码。

    2. 编码兼容的问题,条形码分为几种,常见的需要支持数字,英文大小写,$ + -符号, 以上这些能满足大部分条形码需求。

    3. 字母上方的数字键,需要按住shift + 按键,又由于采用onKeyUp, 所以这时候 shift的keyCode是出现在按键的keyCode之后的, 因此需要借助另一个属性
      shiftKey。此外类似的还有ctrlKey, altKey, 这些属性表明了按键的时候,是否同时按下了 shift, alt,ctrl键(组合键)。

    4. 纯数字条形码,是可以用onChange来处理的。

    全局变量:

    let beforeScanValue = '';
    let flag = false;
    

    组件内:

        const [scanVal, setScanVal] = useState('');
        const [scanValBak, setScanValBak] = useState('');
    		
    	  const scanValueChange = (e) => {
    	        let { value } = e.target;
    	        value = value.replace(/\'/g, '');
    	        if (!value) {
    	            return;
    	        }
    	        if (beforeScanValue) {
    	            if (beforeScanValue !== value) {
    	                value = value.substring(beforeScanValue.length);
    	            }
    	        }
    	        if (flag) {
    	            flag = false;
    	            setScanValBak(value);
    	            return;
    	        }
    	        if (value.includes(beforeScanValue)) {
    	            value = value.replace(beforeScanValue, '');
    	        }
    	        setScanValBak((scanVal) => {
    	            return scanVal + value;
    	        });
    	    };
    	    const enterSearch = (e) => {
    	        // eslint-disable-next-line prefer-const
    	        let inputValue = scanValBak; // e.target.value;
    	        beforeScanValue = inputValue;
    	        flag = true;
    	        setScanValBak('');
    	        setScanVal(inputValue);
    	        console.log('========');
    	        console.log(inputValue, 'enter');
    	        console.log('========');
    	        if (inputValue) {
    	            getItemByScanCode(inputValue);
    	        }
    	    };
    	
    		    <Input
    				ref={scanRef}
    				value={scanVal}
    				style={{  '280px' }}
    				placeholder="请在此处使用扫码枪扫描设备二维码"
    				onPressEnter={enterSearch}
    				onChange={scanValueChange}
    				onBlur={() => {
    					scanRef.current.input.focus();
    				}}
    			/>
    

    2.非焦点元素获取扫码结果

    非焦点元素只能监听onKeyUp事件,在父级元素或根元素上,区别在于不用聚焦。

  • 相关阅读:
    fasterrcnn代码阅读roidata层
    ROI Pooling vs ROI Align
    123
    Learning Efficient Convolutional Networks through Network Slimming
    batch norm结构
    Unity防坑指南之vs修改变量值不会自动同步到Unity
    Unity防坑指南之安装TitleMap
    go静态服务器
    减小 Go 代码编译后的二进制体积
    Go语言出现:CreateProcess error=216, 该版本的 %1 与你运行的 Windows 版本不兼容。
  • 原文地址:https://www.cnblogs.com/chengyunshen/p/16291709.html
Copyright © 2020-2023  润新知