记录--解决扫码枪因输入法中文导致的问题

这篇具有很好参考价值的文章主要介绍了记录--解决扫码枪因输入法中文导致的问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

记录--解决扫码枪因输入法中文导致的问题

问题

最近公司项目上遇到了扫码枪因搜狗/微软/百度/QQ等输入法在中文状态下,使用扫码枪扫码会丢失字符的问题

思考

这种情况是由于扫码枪的硬件设备,在输入的时候,是模拟用户键盘的按键来实现的字符输入的,所以会触发输入法的中文模式,并且也会触发输入法的自动联想。那我们可以针对这个来想解决方案。

方案一

首先想到的第一种方案是,监听keydown的键盘事件,创建一个字符串数组,将每一个输入的字符进行比对,然后拼接字符串,并回填到输入框中,下面是代码:

function onKeydownEvent(e) {
  this.code = this.code || ''
  const shiftKey = e.shiftKey
  const keyCode = e.code
  const key = e.key
  const arr = ['Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-']
  this.nextTime = new Date().getTime()
  const timeSpace = this.nextTime - this.lastTime
  if (key === 'Process') { // 中文手动输入
    if (this.lastTime !== 0 && timeSpace <= 30) {
      for (const a of arr) {
        if (keyCode === 'Key' + a) {
          if (shiftKey) {
            this.code += a
          } else {
            this.code += a.toLowerCase()
          }
          this.lastTime = this.nextTime
        } else if (keyCode === 'Digit' + a) {
          this.code += String(a)
          this.lastTime = this.nextTime
        }
      }
      if (keyCode === 'Enter' && timeSpace <= 30) {
        if (String(this.code)) {
          // TODO
          dosomething....
        }
        this.code = ''
        this.nextTime = 0
        this.lastTime = 0
      }
    }
  } else {
    if (arr.includes(key.toUpperCase())) {
      if (this.lastTime === 0 && timeSpace === this.nextTime) {
        this.code = key
      } else if (this.lastTime !== 0 && timeSpace <= 30) {
        // 30ms以内来区分是扫码枪输入,正常手动输入时少于30ms的
        this.code += key
      }
      this.lastTime = this.nextTime
    } else if (arr.includes(key)) {
      if (this.lastTime === 0 && timeSpace === this.nextTime) {
        this.code = key
      } else if (this.lastTime !== 0 && timeSpace <= 30) {
        this.code += String(key)
      }
      this.lastTime = this.nextTime
    } else if (keyCode === 'Enter' && timeSpace <= 30) {
      if (String(this.code)) {
        // TODO
        dosomething()
      }
      this.code = ''
      this.nextTime = 0
      this.lastTime = 0
    } else {
      this.lastTime = this.nextTime
    }
  }
}

这种方案能解决部分问题,但是在不同的扫码枪设备,以及不同输入法的情况下,还是会出现丢失问题

方案二

使用input[type=password]来兼容不同输入的中文模式,让其只能输入英文,从而解决丢失问题

这种方案网上也有不少的参考
# 解决中文状态下扫描枪扫描错误
# input type=password 取消密码提示框

使用password密码框确实能解决不同输入法的问题,并且Focus到输入框,输入法会被强制切换为英文模式

添加autocomplete="off"autocomplete="new-password"属性

官方文档: # 如何关闭表单自动填充

但是在Chromium内核的浏览器,不支持autocomplete="off",并且还是会出现这种自动补全提示:

记录--解决扫码枪因输入法中文导致的问题

 上面的属性并没有解决浏览器会出现密码补全框,并且在输入字符后,浏览器还会在右上角弹窗提示是否保存:

记录--解决扫码枪因输入法中文导致的问题

先解决密码补全框,这里我想到了一个属性readonly,input原生属性。input[type=password]readonly 时,是不会有密码补全的提示,并且也不会弹窗提示密码保存。

那好,我们就可以在输入前以及输入完成后,将input[type=password]立即设置成readonly

但是需要考虑下面几种情况:

  • 获取焦点/失去焦点时
  • 当前输入框已focus时,再次鼠标点击输入框
  • 扫码枪输出完成最后,输入Enter键时,如果清空输入框,这时候也会显示自动补全
  • 清空输入框时
  • 切换离开页面时

这几种情况都需要处理,将输入框变成readonly

我用vue+element-ui实现了一份,贴上代码:

<template>
  <div class="scanner-input">
    <input class="input-password" :name="$attrs.name || 'one-time-code'" type="password" autocomplete="off" aria-autocomplete="inline" :value="$attrs.value" readonly @input="onPasswordInput">
    <!-- <el-input ref="scannerInput" v-bind="$attrs" v-on="$listeners" @input="onInput"> -->
    <el-input ref="scannerInput" :class="{ 'input-text': true, 'input-text-focus': isFocus }" v-bind="$attrs" v-on="$listeners">
      <template v-for="(_, name) in $slots" v-slot:[name]>
        <slot :name="name"></slot>
      </template>
      <!-- <slot slot="suffix" name="suffix"></slot> -->
    </el-input>
  </div>
</template>

<script>
export default {
  name: 'WispathScannerInput',
  data() {
    return {
      isFocus: false
    }
  },
  beforeDestroy() {
    this.$el.firstElementChild.setAttribute('readonly', true)
    this.$el.firstElementChild.removeEventListener('focus', this.onPasswordFocus)
    this.$el.firstElementChild.removeEventListener('blur', this.onPasswordBlur)
    this.$el.firstElementChild.removeEventListener('blur', this.onPasswordClick)
    this.$el.firstElementChild.removeEventListener('mousedown', this.onPasswordMouseDown)
    this.$el.firstElementChild.removeEventListener('keydown', this.oPasswordKeyDown)
  },
  mounted() {
    this.$el.firstElementChild.addEventListener('focus', this.onPasswordFocus)
    this.$el.firstElementChild.addEventListener('blur', this.onPasswordBlur)
    this.$el.firstElementChild.addEventListener('click', this.onPasswordClick)
    this.$el.firstElementChild.addEventListener('mousedown', this.onPasswordMouseDown)
    this.$el.firstElementChild.addEventListener('keydown', this.oPasswordKeyDown)

    const entries = Object.entries(this.$refs.scannerInput)
    // 解决ref问题
    for (const [key, value] of entries) {
      if (typeof value === 'function') {
        this[key] = value
      }
    }
    this['focus'] = this.$el.firstElementChild.focus.bind(this.$el.firstElementChild)
  },
  methods: {
    onPasswordInput(ev) {
      this.$emit('input', ev.target.value)
      if (ev.target.value === '') {
        this.$el.firstElementChild.setAttribute('readonly', true)
        setTimeout(() => {
          this.$el.firstElementChild.removeAttribute('readonly')
        })
      }
    },
    onPasswordFocus(ev) {
      this.isFocus = true
      setTimeout(() => {
        this.$el.firstElementChild.removeAttribute('readonly')
      })
    },
    onPasswordBlur() {
      this.isFocus = false
      this.$el.firstElementChild.setAttribute('readonly', true)
    },
    // 鼠标点击输入框一瞬间,禁用输入框
    onPasswordMouseDown() {
      this.$el.firstElementChild.setAttribute('readonly', true)
    },
    oPasswordKeyDown(ev) {
      // 判断enter键
      if (ev.key === 'Enter') {
        this.$el.firstElementChild.setAttribute('readonly', true)
        setTimeout(() => {
          this.$el.firstElementChild.removeAttribute('readonly')
        })
      }
    },
    // 点击之后,延迟200ms后放开readonly,让输入框可以输入
    onPasswordClick() {
      if (this.isFocus) {
        this.$el.firstElementChild.setAttribute('readonly', true)
        setTimeout(() => {
          this.$el.firstElementChild.removeAttribute('readonly')
        }, 200)
      }
    },
    onInput(_value) {
      this.$emit('input', _value)
    },
    getList(value) {
      this.$emit('input', value)
    }
    // onChange(_value) {
    //   this.$emit('change', _value)
    // }
  }
}
</script>

<style lang="scss" scoped>
.scanner-input {
  position: relative;
  height: 36px;
  width: 100%;
  display: inline-block;
  .input-password {
    width: 100%;
    height: 100%;
    border: none;
    outline: none;
    padding: 0 16px;
    font-size: 14px;
    letter-spacing: 3px;
    background: transparent;
    color: transparent;
    // caret-color: #484848;
  }
  .input-text {
    font-size: 14px;
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    pointer-events: none;
    background-color: transparent;
    ::v-deep .el-input__inner {
      // background-color: transparent;
      padding: 0 16px;
      width: 100%;
      height: 100%;
    }
  }

  .input-text-focus {
    ::v-deep .el-input__inner {
      outline: none;
      border-color: #1c7af4;
    }
  }
}
</style>

至此,可以保证input[type=password]不会再有密码补全提示,并且也不会再切换页面时,会弹出密码保存弹窗。 但是有一个缺点,就是无法完美显示光标。如果用户手动输入和删除,使用起来会有一定的影响。

本文转载于:

https://juejin.cn/post/7265666505102524475

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

 记录--解决扫码枪因输入法中文导致的问题文章来源地址https://www.toymoban.com/news/detail-710498.html

到了这里,关于记录--解决扫码枪因输入法中文导致的问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ubuntu系统安装好搜狗输入法后只能输入英文,无法输入中文的解决方案

    自己的电脑环境:Ubuntu20.04.5 自己通过搜狗输入法官网下载deb安装包,然后按照如下指令安装搜狗输入法之后 并且完成相关配置。(具体方法参考:Ubuntu 18.04 安装搜狗输入法) 发现,自己只能输入英文,无法输入中文。 主要是因为缺少包导致的。 安装以下两个包: 然后重

    2024年02月11日
    浏览(55)
  • linux(ubuntu22)安装IBus中文输入法及各种问题解决

    之前一直用fcitx4的中文输入法,发现在最新版的QtCreator10中无法输入中文,网上找了各种解决办法都没用,没办法只能用ibus的中文输入法,本文将我在ubuntu22上安装ibus中文输入法的过程记录下来,记录其间遇到的各种问题及对应的解决办法。 在“设置setting”-“区域与语言

    2024年02月15日
    浏览(30)
  • Ubuntu 搜狗输入法无法输入中文解决方案(不需要重装,不需要重启服务器)

    Ubuntu 搜狗输入法突然无法输入中文,上午还好用,下午就不好用了,直接上解决方案 1.终端输入 pidof fcitx 找到搜狗的进程,如下图红框中的就是进程 2.直接杀掉这个进程 3.其实到第二步,如果搜狗输入法自动重启了,就不需要这一步,如果没有重启,就在终端输入 fcitx 重启

    2024年02月04日
    浏览(37)
  • MacOS - 简体中文输入法卡死解决方案(自动化脚本)

    本文使用自动化工具创建应用程序来一键运行脚本重启简体中文输入法的进程,从而解决macOS的假死问题。如果只想看看解决方法的话,可以跳转到“使用‘自动化’工具建立应用程序”段落。 我的电脑使用习惯可谓是很差,软件一直常驻后台,电脑几乎除了系统更新都不关

    2024年01月18日
    浏览(38)
  • 解决Ubuntu18.04安装好搜狗输入法后无法打出中文的问题

    首先下载安装 搜狗拼音输入法 ,下载选择:  x86_64 在ubuntu中设置   fcitx 最后发现安装好了,图标有了 ,但是使用时不能输入中文,使用下面的命令解决:  

    2024年02月05日
    浏览(46)
  • REG.EXE修改注册表-解决win10微软输入法默认中文,将其全局修改为英文

    使用REG.EXE 可以直接强制修改注册表字段 修改注册表: REG.EXE ADD 注册表路径 /v 注册表项字段 /t 注册表字段类型 /d 注册表值 /f 例如: REG. EX ADD HKLMSystemCurrentControlSetServicesWpnUserservice /v Start /t REG_DWORD /d 4 /f 当一些情景下,需要修改每个用户的一些windows设置项且在HKLM下没有

    2024年02月05日
    浏览(39)
  • Ubuntu设置中文输入法

    2024年02月12日
    浏览(37)
  • linux安装搜狗输入法后无法输入中文

    linux安装sogou输入法参考官网教程,https://shurufa.sogou.com/linux/guide 如下图所示,安装后可以在右上角状态栏看到sogou输入法,但是只能输入英文,无法输入中文。 解决方法如下:

    2024年02月13日
    浏览(50)
  • arch配置中文和输入法

    主要解决三点问题 1.显示中文 2.使用中文输入法 3.显示正确的时间 目录 这篇文章旨在教大家如何配置arch中文和中文输入法和对时间的调整 第一步,就是把arch切换成中文 第二步,就是如何使用中文输入法 时间问题解决 我arch版本是 archlinux2024.3.29 X86-64 桌面环境是 KDE 6.0.3 !注意

    2024年04月08日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包