如何在input标签中捕获条码扫描器输出的十六进制按键序列
问题根因
你现有代码失效的核心原因是keypress事件仅会对可打印字符触发,Tab、Enter这类控制键不会进入keypress回调,默认行为自然无法拦截。同时没有做失焦兜底,控制键触发失焦后后续扫描内容就会丢失。
可行解决方案
直接用keydown事件监听所有按键输入,配合失焦兜底逻辑即可100%捕获全部字节序列,不需要修改扫描器配置,纯Web端实现:
1. HTML代码
可以保留现有form结构,也可以将输入框设为透明不影响UI展示,只要保持输入框持续获取焦点即可:
<form onsubmit="return false;"> <input type="text" id="barcode" name="barcode" autofocus style="opacity: 0; position: absolute; top: 0; left: 0; width: 0; height: 0;"> </form>
2. JS逻辑代码
// 存储单次扫描的十六进制字节数组 let barcodeBuffer = []; // 扫描超时判定阈值,单位毫秒,可根据设备扫描速度调整,默认50ms无输入即判定扫描结束 const SCAN_TIMEOUT = 50; let scanTimer = null; const $input = $('#barcode'); // 页面加载后自动聚焦输入框 $input.trigger('focus'); // 监听所有按键的keydown事件,控制键也会触发 $input.on('keydown', function(e) { // 第一步就拦截所有默认行为:失焦、提交、字符输入等 e.preventDefault(); e.stopPropagation(); // 转成两位十六进制,不足补前导0 const hexByte = e.which.toString(16).padStart(2, '0'); barcodeBuffer.push(hexByte); // 实时查看单个字节可打开下面的日志 // console.log('捕获字节:', hexByte); // 重置超时定时器 clearTimeout(scanTimer); scanTimer = setTimeout(() => { // 扫描结束,拼接完整十六进制串 const fullScanHex = barcodeBuffer.join(''); // 此处替换为你的业务逻辑:传入Apex后端、解密处理等 console.log('完整扫描结果:', fullScanHex); // 清空缓冲区等待下一次扫描 barcodeBuffer = []; }, SCAN_TIMEOUT); }); // 失焦兜底:任何原因导致输入框失焦都立刻拉回焦点,避免扫描中断 $input.on('blur', function() { setTimeout(() => $input.trigger('focus'), 10); }); // 双重拦截表单提交 $('form').on('submit', e => e.preventDefault());
补充说明
- 超时阈值
SCAN_TIMEOUT可根据实际扫描速度调整,范围在20~100ms之间都可正常区分扫描枪输入和人工输入,不会出现串包问题 - 如果需要展示扫描状态,也可以去掉输入框的透明样式,自定义展示逻辑
- 如果你的设备内核是Chrome 89以上版本,也可以用WebHID API直接对接扫描硬件,不需要依赖Keyboard Wedge,直接读取原始扫描数据,该方案不需要输入框持续聚焦,但需要用户首次使用时授权设备访问权限。
内容的提问来源于stack exchange,提问作者Superdooperhero
相关产品推荐
相关产品推荐

