/**
* @property {RegExp[]} patterns
* @property {function(code:string):void} onScanSuccess
*/
class CodeScanner {
/**
* @param {(code:string)=>{}} handler
* @param {RegExp[]} patterns
*/
constructor(handler, patterns = []) {
this.resetScan()
this.patterns = patterns || []
this.onScanSuccess = handler || ((code) => {
console.log(code)
})
}
/**
* 开始监听
*/
start() {
this.resetScan()
const that = this
this.thatKeyHandler = (e) => {
that._keyHandler(e)
}
document.addEventListener("keypress", this.thatKeyHandler, { passive: true })
}
/**
* 停止接听
*/
stop() {
this.resetScan()
document.removeEventListener("keypress", this.thatKeyHandler)
}
/**
*
* @param {KeyboardEvent} e
* @private
*/
_keyHandler(e) {
if (["INPUT", "TEXTAREA", "BUTTON"].indexOf(document.activeElement.nodeName) >= 0) {
return // 焦点在其它输入框时不触发
}
if (this.scanLastTimeStamp === 0) {
this.code = e.key
this.scanLastTimeStamp = e.timeStamp
return
}
if (e.timeStamp - this.scanLastTimeStamp > 50) {
return this.resetScan("超过扫描间隔的阈值(毫秒)")
}
if (e.key === "Enter") {
let ok = this.patterns.length === 0
for (let i = 0; i < this.patterns.length; i++) {
if (this.code.match(this.patterns[i])) {
ok = true
break
}
}
if (ok) {
if (this.onScanSuccess !== null) {
this.onScanSuccess(this.code)
}
return this.resetScan("正常结束扫描")
} else {
return this.resetScan("扫描码不符合规则")
}
}
this.code += e.key
this.scanLastTimeStamp = e.timeStamp
}
/**
* @param {?string} reason
*/
resetScan(reason = null) {
if (reason) {
console.log(reason,this.code)
}
this.scanLastTimeStamp = 0
this.code = ""
}
}