master
宇天 2020-11-03 14:59:31 +08:00
parent b68974c6f0
commit d6ca6d7133
3 changed files with 98 additions and 35 deletions

View File

@ -4,3 +4,30 @@
![keyboard](./keyboard.jpg) ![keyboard](./keyboard.jpg)
### 辅助功能键
> 辅助功能键, 不支持单独设置热键。
>> 包括 `Ctrl、Shift、Alt/Option、Win/Cmd` 这4个。
## 普通按键
> 即除了辅助功能键以外的其他按键。可以单独设置, 也可以配合辅助按键组合使用。
>> 但是, 不允许在一组里出现多次。如需要, 请分组。
```js
var kb = new Keyboard()
// 同时出现C和V这2个普通按键, 是不允许的,
kb.on(['ctrl + c + v'], ev => {
// todo...
})
// 须改成分2组写
kb.on(['ctrl + c', 'ctrl + v'], ev => {
// todo...
})
```

View File

@ -4,7 +4,7 @@
* @date 2020/10/29 16:48:26 * @date 2020/10/29 16:48:26
*/ */
import { KEY_DICT, MULTI_KEYS } from './key.dict.js' import { KEY_DICT, MULTI_KEYS, MULTI_KEY_CODES } from './key.dict.js'
var log = console.log var log = console.log
@ -19,11 +19,26 @@ function unbind(fn) {
export default class Keyboard { export default class Keyboard {
constructor() { constructor() {
this.__EVENTS__ = {} this.__EVENTS__ = []
this.__LAST__ = {}
this.__TIME__ = 0
this._keydown = bind(ev => { this._keydown = bind(ev => {
if (MULTI_KEY_CODES.includes(ev.keyCode)) {
return
}
for (let k in this.__EVENTS__) { for (let k in this.__EVENTS__) {
var item = this.__EVENTS__[k] var item = this.__EVENTS__[k]
if (item.check(ev)) { var res = item.check(ev)
if (res) {
this.__LAST__[k]++
} else {
this.__LAST__[k] = -1
}
log('-------------------', res, this.__LAST__[k])
if (this.__LAST__[k] + 1 === item.dict.length) {
item.fn.forEach(function(fn) { item.fn.forEach(function(fn) {
fn(ev) fn(ev)
}) })
@ -41,45 +56,64 @@ export default class Keyboard {
on(act, callback) { on(act, callback) {
var key = [] var key = []
var dict = [] var dict = []
var passed = true // 语法检测通过
var _this = this
act.forEach(it => { act.forEach(it => {
var tmp = {} var tmp = []
dict.push(tmp) dict.push(tmp)
it = it.split('+').map(k => { it = it.split('+').map(k => {
k = k.trim().toLowerCase() k = k.trim().toLowerCase()
tmp[k] = KEY_DICT[k] if (MULTI_KEYS[k]) {
if (tmp.includes(k)) {
passed = false
console.error('功能键,同组中不能重复。⎣%s⎤', it)
} else {
tmp.push(k)
}
} else {
if (tmp.key) {
passed = false
console.error('非功能键,同组不能出现多个。⎣%s⎤', it)
} else {
tmp.key = KEY_DICT[k]
}
}
return k return k
}) })
key.push(it.join('+')) key.push(it.join('+'))
}) })
if (passed) {
key = key.join(',') key = key.join(',')
this.__LAST__[key] = -1
if (this.__EVENTS__[key]) { if (this.__EVENTS__[key]) {
this.__EVENTS__[key].fn.push(callback) this.__EVENTS__[key].fn.push(callback)
} else { } else {
this.__EVENTS__[key] = { this.__EVENTS__[key] = {
key,
dict, dict,
check(ev) { check(ev) {
var { keyCode, code } = ev var now = Date.now()
var now = 0 var idx = _this.__LAST__[this.key]
var actions = this.dict.concat() var action = this.dict[idx + 1]
var action = actions.shift()
var checked = false var checked = false
log('check: ', keyCode, code, ev) if (action) {
checked = ev.keyCode === action.key
while (action) { if (idx > -1) {
if (now === 0) { if (now - _this.__TIME__ > 100) {
} else {
var _now = Date.now()
if (_now - now > 100) {
checked = false checked = false
break
} }
now = _now
} }
action = actions.shift() if (checked) {
for (let k of action) {
checked = ev[`${k}Key`]
}
}
log(action, now, checked)
} }
return checked return checked
@ -87,6 +121,6 @@ export default class Keyboard {
fn: [callback] fn: [callback]
} }
} }
log(this.__EVENTS__) }
} }
} }

View File

@ -3,9 +3,11 @@ export const MULTI_KEYS = {
ctrl: 1, ctrl: 1,
shift: 1, shift: 1,
alt: 1, alt: 1,
super: 1 meta: 1
} }
export const MULTI_KEY_CODES = [16, 17, 18, 91]
// 按键对应的code值 // 按键对应的code值
export const KEY_DICT = { export const KEY_DICT = {
'0': 48, // Digit{N}, Numpad{N} '0': 48, // Digit{N}, Numpad{N}
@ -62,7 +64,7 @@ export const KEY_DICT = {
ctrl: 17, // ControlLeft, ControlRight ctrl: 17, // ControlLeft, ControlRight
alt: 18, // AltLeft, AltRight alt: 18, // AltLeft, AltRight
space: 32, space: 32,
super: 91, // MetaLeft, MetaRight meta: 91, // MetaLeft, MetaRight
tab: 9, tab: 9,
backspace: 8, backspace: 8,
numlock: 12, numlock: 12,