Merge remote-tracking branch 'origin/master'
commit
5b5d69d353
@ -0,0 +1,203 @@
|
||||
import { onHide, onShow, onUnload } from '@dcloudio/uni-app'
|
||||
|
||||
const androidKeyCodeMap = {
|
||||
7: '0',
|
||||
8: '1',
|
||||
9: '2',
|
||||
10: '3',
|
||||
11: '4',
|
||||
12: '5',
|
||||
13: '6',
|
||||
14: '7',
|
||||
15: '8',
|
||||
16: '9',
|
||||
29: 'A',
|
||||
30: 'B',
|
||||
31: 'C',
|
||||
32: 'D',
|
||||
33: 'E',
|
||||
34: 'F',
|
||||
35: 'G',
|
||||
36: 'H',
|
||||
37: 'I',
|
||||
38: 'J',
|
||||
39: 'K',
|
||||
40: 'L',
|
||||
41: 'M',
|
||||
42: 'N',
|
||||
43: 'O',
|
||||
44: 'P',
|
||||
45: 'Q',
|
||||
46: 'R',
|
||||
47: 'S',
|
||||
48: 'T',
|
||||
49: 'U',
|
||||
50: 'V',
|
||||
51: 'W',
|
||||
52: 'X',
|
||||
53: 'Y',
|
||||
54: 'Z',
|
||||
55: ',',
|
||||
56: '.',
|
||||
69: '-',
|
||||
70: '=',
|
||||
71: '[',
|
||||
72: ']',
|
||||
73: '\\',
|
||||
74: ';',
|
||||
75: "'",
|
||||
76: '/',
|
||||
81: '+'
|
||||
}
|
||||
|
||||
export function useScannerInput(options = {}) {
|
||||
const minLength = Number(options.minLength ?? 3)
|
||||
const commitDelay = Number(options.commitDelay ?? 120)
|
||||
const uppercase = options.uppercase !== false
|
||||
const ignoreInputTarget = options.ignoreInputTarget !== false
|
||||
const hideKeyboardOnScan = options.hideKeyboardOnScan !== false
|
||||
const hideKeyboardOnLeave = options.hideKeyboardOnLeave !== false
|
||||
const onScan = typeof options.onScan === 'function' ? options.onScan : () => {}
|
||||
|
||||
let scannerBuffer = ''
|
||||
let scannerTimer = null
|
||||
let scannerListening = false
|
||||
let plusKeyListening = false
|
||||
|
||||
function getScannerEventTarget() {
|
||||
if (typeof document !== 'undefined') return document
|
||||
if (typeof window !== 'undefined') return window
|
||||
return null
|
||||
}
|
||||
|
||||
function registerScannerListener() {
|
||||
if (scannerListening) return
|
||||
const target = getScannerEventTarget()
|
||||
if (target?.addEventListener) {
|
||||
target.addEventListener('keydown', handleScannerKeydown)
|
||||
scannerListening = true
|
||||
}
|
||||
registerPlusKeyListener()
|
||||
}
|
||||
|
||||
function unregisterScannerListener() {
|
||||
const target = getScannerEventTarget()
|
||||
if (scannerListening && target?.removeEventListener) {
|
||||
target.removeEventListener('keydown', handleScannerKeydown)
|
||||
}
|
||||
scannerListening = false
|
||||
unregisterPlusKeyListener()
|
||||
clearScannerBuffer()
|
||||
if (hideKeyboardOnLeave) hideSoftKeyboard()
|
||||
}
|
||||
|
||||
function registerPlusKeyListener() {
|
||||
if (plusKeyListening) return
|
||||
if (typeof plus === 'undefined' || !plus?.key?.addEventListener) return
|
||||
plus.key.addEventListener('keydown', handlePlusScannerKeydown)
|
||||
plusKeyListening = true
|
||||
}
|
||||
|
||||
function unregisterPlusKeyListener() {
|
||||
if (!plusKeyListening) return
|
||||
if (typeof plus !== 'undefined' && plus?.key?.removeEventListener) {
|
||||
plus.key.removeEventListener('keydown', handlePlusScannerKeydown)
|
||||
}
|
||||
plusKeyListening = false
|
||||
}
|
||||
|
||||
function handlePlusScannerKeydown(event) {
|
||||
handleScannerKeydown({ ...event, isPlusKeyEvent: true })
|
||||
}
|
||||
|
||||
function handleScannerKeydown(event) {
|
||||
if (ignoreInputTarget) {
|
||||
const targetTag = String(event?.target?.tagName || '').toLowerCase()
|
||||
if (targetTag === 'input' || targetTag === 'textarea') return
|
||||
}
|
||||
|
||||
const key = normalizeScannerKey(event)
|
||||
if (!key) return
|
||||
if (key === 'Enter') {
|
||||
commitScannerBuffer()
|
||||
return
|
||||
}
|
||||
|
||||
scannerBuffer += key
|
||||
if (scannerTimer) clearTimeout(scannerTimer)
|
||||
scannerTimer = setTimeout(() => {
|
||||
commitScannerBuffer()
|
||||
}, commitDelay)
|
||||
}
|
||||
|
||||
function normalizeScannerKey(event) {
|
||||
if (event?.ctrlKey || event?.altKey || event?.metaKey) return ''
|
||||
if (isAndroidPlusKeyEvent(event)) return normalizeAndroidKeyCode(event)
|
||||
|
||||
const key = event?.key
|
||||
if (key === 'Enter' || key === 'Tab') return 'Enter'
|
||||
if (typeof key === 'string' && key.length === 1) return uppercase ? key.toUpperCase() : key
|
||||
|
||||
const code = Number(event?.keyCode || event?.which || 0)
|
||||
if (code === 13 || code === 9) return 'Enter'
|
||||
if (code >= 48 && code <= 90) {
|
||||
const value = String.fromCharCode(code)
|
||||
return uppercase ? value.toUpperCase() : value
|
||||
}
|
||||
if (code >= 96 && code <= 105) return String(code - 96)
|
||||
if (code === 189 || code === 109) return '-'
|
||||
if (code === 190 || code === 110) return '.'
|
||||
return ''
|
||||
}
|
||||
|
||||
function isAndroidPlusKeyEvent(event) {
|
||||
return Boolean(event?.isPlusKeyEvent)
|
||||
}
|
||||
|
||||
function normalizeAndroidKeyCode(event) {
|
||||
const code = Number(event?.keyCode || event?.which || 0)
|
||||
if (code === 66 || code === 61 || code === 160) return 'Enter'
|
||||
const value = androidKeyCodeMap[code] || ''
|
||||
return uppercase ? value.toUpperCase() : value.toLowerCase()
|
||||
}
|
||||
|
||||
function clearScannerBuffer() {
|
||||
scannerBuffer = ''
|
||||
if (scannerTimer) {
|
||||
clearTimeout(scannerTimer)
|
||||
scannerTimer = null
|
||||
}
|
||||
}
|
||||
|
||||
async function commitScannerBuffer() {
|
||||
const value = scannerBuffer.trim()
|
||||
clearScannerBuffer()
|
||||
if (value.length < minLength) return
|
||||
if (hideKeyboardOnScan) hideSoftKeyboard()
|
||||
await onScan(value)
|
||||
}
|
||||
|
||||
function hideSoftKeyboard() {
|
||||
try {
|
||||
uni.hideKeyboard()
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
onShow(() => {
|
||||
registerScannerListener()
|
||||
})
|
||||
|
||||
onHide(() => {
|
||||
unregisterScannerListener()
|
||||
})
|
||||
|
||||
onUnload(() => {
|
||||
unregisterScannerListener()
|
||||
})
|
||||
|
||||
return {
|
||||
clearScannerBuffer,
|
||||
registerScannerListener,
|
||||
unregisterScannerListener
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,88 @@
|
||||
{
|
||||
"id": "sv-focus-no-keyboard",
|
||||
"displayName": "输入框聚焦且阻止键盘弹出",
|
||||
"version": "1.0.2",
|
||||
"description": "使输入框在聚焦的同时,从根本上阻止软键盘弹出,并非是单纯的隐藏键盘",
|
||||
"keywords": [
|
||||
"聚焦",
|
||||
"键盘",
|
||||
"光标",
|
||||
"focus",
|
||||
"keyboard"
|
||||
],
|
||||
"repository": "",
|
||||
"engines": {
|
||||
"HBuilderX": "^3.1.0"
|
||||
},
|
||||
"dcloudext": {
|
||||
"type": "component-vue",
|
||||
"sale": {
|
||||
"regular": {
|
||||
"price": "0.00"
|
||||
},
|
||||
"sourcecode": {
|
||||
"price": "0.00"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"qq": ""
|
||||
},
|
||||
"declaration": {
|
||||
"ads": "无",
|
||||
"data": "插件不采集任何数据",
|
||||
"permissions": "无"
|
||||
},
|
||||
"npmurl": ""
|
||||
},
|
||||
"uni_modules": {
|
||||
"dependencies": [],
|
||||
"encrypt": [],
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "y",
|
||||
"aliyun": "y",
|
||||
"alipay": "y"
|
||||
},
|
||||
"client": {
|
||||
"Vue": {
|
||||
"vue2": "y",
|
||||
"vue3": "y"
|
||||
},
|
||||
"App": {
|
||||
"app-vue": "y",
|
||||
"app-nvue": "n",
|
||||
"app-uvue": "n",
|
||||
"app-harmony": "u"
|
||||
},
|
||||
"H5-mobile": {
|
||||
"Safari": "y",
|
||||
"Android Browser": "y",
|
||||
"微信浏览器(Android)": "y",
|
||||
"QQ浏览器(Android)": "y"
|
||||
},
|
||||
"H5-pc": {
|
||||
"Chrome": "y",
|
||||
"IE": "y",
|
||||
"Edge": "y",
|
||||
"Firefox": "y",
|
||||
"Safari": "y"
|
||||
},
|
||||
"小程序": {
|
||||
"微信": "n",
|
||||
"阿里": "n",
|
||||
"百度": "n",
|
||||
"字节跳动": "n",
|
||||
"QQ": "n",
|
||||
"钉钉": "n",
|
||||
"快手": "n",
|
||||
"飞书": "n",
|
||||
"京东": "n"
|
||||
},
|
||||
"快应用": {
|
||||
"华为": "n",
|
||||
"联盟": "n"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue