问题一:扫码枪不获取焦点直接输入
扫码枪类似键盘,就是一个输入设备。点击输入框再扫码就相当于键盘直接输入。现在要实现进入页面就能够直接扫码查询。
解决思路:通过js的键盘监听事件,每次输入都可以获取当前输入的字符。因为扫码枪与键盘一样,都是一个个输入,所以需要将输入的字符保存起来。
但若页面还有需要用户手动输入的输入框,键盘监听事件仍能监听,所以需要区分扫码枪输入和手动输入。因为扫码枪输入字符间时间间隔很小,所以可以通过判断与上一次输入的时间间隔来判断是扫码枪输入还是手动输入,间隔比较小,则把当前字符保存,反之清空保存的字符。
如何判断扫码枪输入结束?大多数扫码枪都是以回车键结束,可以进行回车键判断,若输入了回车键,则扫码结束,执行之后的逻辑
问题二:扫码枪中英文输入法导致输入出错问题
扫码枪用中文输入法会导致输入错误的结果,需要在英文输入法下进行
解决思路:js没有能直接改变操作系统输入法的方法,但html中的密码框只能够输入英文,当密码框获取焦点时,就会自动把输入法切换成英文。所以可以通过一个隐藏的密码框,一进入页面就使其获取焦点再失去焦点。
但这时产品经理又要说了:“万一进入页面后客户不小心点到了,又切换成中文输入法怎么办?”我:“ **** ”。这就需要通过键盘监听事件,在输入前进行密码框的获取失去焦点,但如果页面有需要手动输入的输入框,就会导致获取不到焦点的问题,这就需要判断输入时是否有输入框获取了焦点,没有则代表是扫码枪输入,切换成英文输入法。
代码(Vue):
html:
<el-dialog :title="title" :visible.sync="open" width="900px" append-to-body @close="cancel">
<el-form ref="form" :model="form" :rules="rules" label-width="120px" :disabled="isLook">
<el-row>
<el-col :span="18">
<el-form-item label="疗程卡编号" prop="code">
<el-input v-model="form.code" placeholder="请输入疗程卡编号"
@focus="isFocus=true" @blur="isFocus=false"/>
</el-form-item>
</el-col>
<el-row>
<el-col :span="12">
<el-form-item label="核销次数" prop="amount">
<el-input v-model="form.amount" type="number" placeholder="请输入核销次数"
@focus="isFocus=true" @blur="isFocus=false"/>
</el-form-item>
</el-col>
</el-row>
<el-input style="opacity: 0;" ref="hideInput" type="password"></el-input>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm" v-if="!isLook">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</el-dialog>
这里通过定义一个isFocus来判断是否有输入框获取了焦点
键盘监听事件:
mounted(){
//创建监听器
document.addEventListener('keydown', this.handleScanCode)
},
beforeDestroy() {
//移除监听器
document.removeEventListener('keydown', this.handleScanCode)
},
/**
* 监听扫码枪输入
*/
handleScanCode(event){
if (event.key === 'Backspace' || event.keyCode === 8) {
// 允许退格键的默认行为
return;
}
let nowDate=new Date()
if(!this.isFocus && (!this.scanData.lastTime || nowDate-this.scanData.lastTime>500)){
//没有输入框获取焦点,输入法修改成英文
this.$nextTick(()=>{
this.$refs.hideInput.focus()
this.$refs.hideInput.blur()
})
}
//距离上次输入时间大于1秒
if(this.scanData.lastTime && nowDate-this.scanData.lastTime>500){
this.scanData.chars=""
}
this.scanData.lastTime=nowDate
//扫码枪以回车键结束
if (event.keyCode === 13) {
if (this.scanData.chars) {
this.$set(this.form, "code", this.scanData.chars);
//查询用户疗程卡
this.getCardInfo();
}
}else{
//保存前面的值
this.scanData.chars+=event.key
}
},