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