解决扫码枪中文输入法下条形码内容丢失问题

前端

扫码枪的工作原理

扫码枪的基本工作原理是模拟键盘输入。它将扫描到的条码或二维码解析后的数据,以极快的速度输入到当前获得焦点的输入框中,并在数据末尾追加一个回车(Enter)键。这种方法在英文输入法模式下运行良好,但在中文输入模式下可能会出现一些问题,比如录入不完整、小写字母被转换为中文字符等。

问题背景

在实际应用中,特别是在中文环境下,用户和客户反馈了上述问题。为了改善用户体验,在领导与客户的强大动力支持下,我们开始探索解决方案。

解决方案

经过一系列的测试和优化,最终摸索出以下基于onscan.js库的解决方案:

  1. 正确录入:确保在中文模式下也能正确录入数字、大小写字母以及英文特殊字符。
  2. 内容清空:扫码后自动清空原有的输入内容,展示新的条码内容。
  3. 多种输入方式:支持扫码输入和手动输入两种方式。

跳板机会

技术大厂→跳板,前端-测试-后端,待遇和稳定性都还不错,感兴趣可以试试~

实现代码

<template>
  <el-input
    ref="snRef"
    v-model="sortingInfo.sn"
    placeholder="扫码或输入"
  />
</template>
<script setup>
import { ref, useTemplateRef, onMounted, onBeforeUnmount } from 'vue'
import onScan from 'onscan.js'
  
let timer = null
const snRef = useTemplateRef('snRef')
const sortingInfo = ref({ sn: '' })
const code = ref('') // 拼接扫码内容
let lastKeyTime = 0 // 用于判断是否为扫码输入的基准时间
let isScaning = false // 是否为扫码输入
let cacheLastKey = '' // 缓存最后一个被判定为非扫码输入的字符

onMounted(() => {
  onScan.attachTo(snRef.value.input, {
    async onKeyProcess(char, event) {
      if (event.key === 'Shift') {
        event.preventDefault()
      }
      const now = Date.now()
      // 输入间隔小于50毫秒判定为扫码输入
      isScaning = now - lastKeyTime <= 50
      lastKeyTime = now
      // console.log(307, isScaning, event)

      // 保存最后一个被判定为手动输入的字符:可能是扫码输入的第一个字符
      if (!isScaning && event.key && event.key.length === 1) {
        cacheLastKey = event.key
      }
      // 被识别为扫码输入时已经是第二个字符了,需要将保存的第一个字符作为扫码内容的初始值
      if (isScaning && cacheLastKey) {
        code.value = cacheLastKey
        cacheLastKey = ''
        
      }
      // 仅字符长度是1的拼接至code中
      if (event.key && event.key.length === 1) {
        code.value += event.key
      }
      // 扫码最终以‘Enter’键结尾
      if (event.key === 'Enter' && isScaning) {
        if (timer) {
          clearTimeout(timer)
        }
        if (snInputFocus()) {
          sortingInfo.value = { sn: '' }
          // 延迟执行,解决中文模式下未偶发完全清空的数据:原因未知
          timer = setTimeout(() => {
            sortingInfo.value.sn = code.value
            handleSearch()
          }, 150)
        }
      }
    },
  })
})
onBeforeUnmount(() => {
  onScan.detachFrom(snRef.value.input)
})

function snInputFocus() {
  const inputElement = snRef.value.input // 获取实际的input DOM元素
  return document.activeElement === inputElement
}
</script>

选用原因

  1. 避免自动填充:使用input[type=password]时会有自动填充下拉框和记住密码弹窗,影响用户体验。
  2. 兼容性问题:在中文模式下,onscan.js无法触发onScan回调函数。
  3. 事件监听:在中文模式下监听input标签的keyPress事件时,无法正确监听小写字母录入。

遗留问题

输入法切换:中途切换输入法(例如点击Caps Lock键),可能导致扫码枪切换为大写模式,从而影响录入结果。

通过上述解决方案,我们能够在中文环境下有效解决扫码枪的录入问题,提升用户的使用体验。

——转载自:aol121

0
0
0
0
关于作者
关于作者

文章

0

获赞

0

收藏

0

相关资源
火山引擎音视频体验白皮书
火山引擎联合AMD发布了音视频体验白皮书,以抖音亿级日活用户实践和大规模场景落地经验,详细解读音视频体验评估指标和模型,分享火山引擎音视频实验室的评测方案和抖音在音视频体验优化上的典型策略、案例,助力企业优化用户体验,促进业务增长。
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论