js通过扫描枪快速扫码录入的功能实现(区分手动输入和扫码枪录入)-pc
生活随笔
收集整理的這篇文章主要介紹了
js通过扫描枪快速扫码录入的功能实现(区分手动输入和扫码枪录入)-pc
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
掃碼錄入實踐
- 實踐背景
- 需要解決的問題
- 代碼實現(xiàn)
- 最終代碼
- 結(jié)語
實踐背景
在近期工作過程中接手了一個讓我有些棘手的需求,需求如下:
需要解決的問題
代碼實現(xiàn)
因為我們要注冊的為全局事件,但是又不能影響到其他頁面所以我們可以借助vue的生命周期來注冊卸載。樓主這里因為頁面切換用的是keeplive所以我是將事件注冊放到了 created() 和 activated()中
(1) 因為我們要在頁面任意位置識別并聚焦到固定的input中,所以我們需要把事件放到document上面
(2) 因為keydown事件按下不抬起會一直觸發(fā),所以這里我們采用keyup事件更加友好。
(3) 我們這里使用了addEventListener注冊事件,removeEventListener來刪除事件。這兩個方法有三個參數(shù),分別為 (“事件名”,“事件觸發(fā)的函數(shù)”,“采用捕獲還是冒泡”) 。這里我就不做贅述了,詳細說明查看下面文檔:官方文檔 或者 相關(guān)博客例如:https://blog.csdn.net/l908825925/article/details/107865676
PS: 此處需注意一個細節(jié),添加事件和刪除事件的所有參數(shù)必須一致,否則會導(dǎo)致無法刪除
methods:{// 添加事件addKeyUp(){document.addEventListener("keyup",this.documentKeyUp,true)}// 刪除事件removeKeyUp(){document.removeEventListener("keyup",this.documentKeyUp,true)}}因為我們將事件注冊到了document所以我們的keyup事件必然會影響到輸入,我們要避免中情況我們就需要禁止頁面上所有的事件冒泡,導(dǎo)致執(zhí)行document上的keyup事件觸發(fā)。那么我們怎么去判斷呢,我這邊采用的分析event數(shù)據(jù)中的event.srcElement.tagName來進行判斷。每一個元素的tagName都不一樣所以我們只需要判斷我們keyup時的event.srcElement.tagName是否等于 “INPUT” || "TEXTAREA "
問題分析:
這個問題我們需要從硬件去分析,首先,掃碼搶輸入特點為快速錄入自動在輸入結(jié)束觸發(fā)回車,人為按鍵輸入相對掃碼槍輸入較慢,手動觸發(fā)回車事件。那么我們從哪兒來拿到這個時間呢,通過分析event得出timeStamp字段,返回事件發(fā)生時的時間戳,掃碼槍每次錄入是8-10毫秒,手動錄入為則在80-120毫秒左右,好一點的設(shè)備也會有在30毫秒左右,那么我們就可以用這個時間差來做區(qū)分手動錄入和掃碼槍錄入。
所以代碼邏輯如下:
最終代碼
input 組件模塊
<el-input ref="selectGoods" v-model="searchText" @focus="selectFocus()" @keyup="keyUpEvent" /> // input組件代碼 export default {data() {return { // 存放每次keyup事件時間戳keyUpIntervalArray: [],// 儲存每一次按鍵的內(nèi)容當(dāng)讓輸入框組件獲取焦點時拿到內(nèi)容直接錄入商品scanText:""// 是否為掃碼錄入scangGun:false}},methods:{// input 函數(shù)selectFocus(){ this.$refs["selectGoods"].select() },// input 函數(shù)keyUpEvent(){if(event?.keyCode === 13 && this.searchText) this.inputGetData(this.scangGun?"":"handle")this.keyUpIntervalArray = util.clone(this.keyUpIntervalArray.splice(this.keyUpIntervalArray.length-5,5))this.keyUpIntervalArray.push(event.timeStamp)if(this.keyUpIntervalArray.length<2) returnfor(let i in this.keyUpIntervalArray){let num = Math.ceil(this.keyUpIntervalArray[this.keyUpIntervalArray.length-1]) - Math.ceil(this.keyUpIntervalArray[this.keyUpIntervalArray.length-2])this.scangGun = num < 20 && num !=0 ? true : falseif(i>0&&this.keyUpIntervalArray.length === parseInt(i)+1){if(this.scangGun) return}}}} }document相關(guān)處理
export default {data() {return { // 存放每次keyup事件時間戳keyUpIntervalArray: [],// 儲存每一次按鍵的內(nèi)容當(dāng)讓輸入框組件獲取焦點時拿到內(nèi)容直接錄入商品scanText:"",// 是否通過create生命周期isCreate: false}},created() {this.isCreate = truethis.addKeyUp()},activated() {if (!this.isCreate) this.addKeyUp() },destroyed(){this.removeKeyUp()},deactivated() {this.removeKeyUp()this.isCreate = false},methods:{// 添加事件addKeyUp(){document.addEventListener("keyup",this.documentKeyUp,true)},// 刪除事件removeKeyUp(){document.removeEventListener("keyup",this.documentKeyUp,true)},// document事件處理documentKeyUp(event){// event.key.length>1if(["TEXTAREA","INPUT"].includes(event.srcElement.tagName) || event.key.length>1) return this.scanText = ""let temp = this.keyUpIntervalArray// 校驗輸入let pattern = /\d|\s|[a-zA-Z]/if(pattern.test(event.key))this.scanText += event.key// 只存少量時間戳temp = util.clone(temp.splice(temp.length-5,5))temp.push(event.timeStamp)this.keyUpIntervalArray = temp// 當(dāng)儲存的小于按鍵事件時間戳小于2無法對比,則不做判斷if(temp.length<2) returnfor(let i in temp){let num = Math.ceil(temp[temp.length-1]) - Math.ceil(temp[temp.length-2])if(num < 20 && num !=0) this.$refs['selectGoods']?.focus(this.scanText)}}}}PS: 補充內(nèi)容:
1、中文輸入法掃碼槍掃碼會導(dǎo)致很多鍵位識別為229。導(dǎo)致無法識別設(shè)備回車。 2、部分老式掃碼槍在中文大寫模式下錄入完成最后一個鍵位code不是13(回車),而是20(Caps_Lock, 大小寫切換)結(jié)語
該文章是為個人的思路及實現(xiàn)的實踐總結(jié),代碼并不嚴(yán)謹(jǐn)優(yōu)雅,希望對各位開發(fā)者有所啟發(fā),若有不足還望多多指教。
總結(jié)
以上是生活随笔為你收集整理的js通过扫描枪快速扫码录入的功能实现(区分手动输入和扫码枪录入)-pc的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 自相关、互相关函数学习笔记
- 下一篇: mybatis中aplication.p