diff --git a/Readme.md b/Readme.md index 7d6e149..abd64cf 100644 --- a/Readme.md +++ b/Readme.md @@ -3,4 +3,31 @@ >> 1.0版 功能键(Shift, Ctrl, Alt/Option, Win/Cmd)不区分左右。 -![keyboard](./keyboard.jpg) \ No newline at end of file +![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... +}) + +``` + + diff --git a/src/index.es7 b/src/index.es7 index e4ed748..2b654e2 100644 --- a/src/index.es7 +++ b/src/index.es7 @@ -4,7 +4,7 @@ * @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 @@ -19,11 +19,26 @@ function unbind(fn) { export default class Keyboard { constructor() { - this.__EVENTS__ = {} + this.__EVENTS__ = [] + this.__LAST__ = {} + this.__TIME__ = 0 + this._keydown = bind(ev => { + if (MULTI_KEY_CODES.includes(ev.keyCode)) { + return + } for (let k in this.__EVENTS__) { 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) { fn(ev) }) @@ -41,52 +56,71 @@ export default class Keyboard { on(act, callback) { var key = [] var dict = [] + var passed = true // 语法检测通过 + var _this = this act.forEach(it => { - var tmp = {} + var tmp = [] dict.push(tmp) it = it.split('+').map(k => { 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 }) key.push(it.join('+')) }) - key = key.join(',') + if (passed) { + key = key.join(',') + this.__LAST__[key] = -1 - if (this.__EVENTS__[key]) { - this.__EVENTS__[key].fn.push(callback) - } else { - this.__EVENTS__[key] = { - dict, - check(ev) { - var { keyCode, code } = ev - var now = 0 - var actions = this.dict.concat() - var action = actions.shift() - var checked = false + if (this.__EVENTS__[key]) { + this.__EVENTS__[key].fn.push(callback) + } else { + this.__EVENTS__[key] = { + key, + dict, + check(ev) { + var now = Date.now() + var idx = _this.__LAST__[this.key] + var action = this.dict[idx + 1] + var checked = false - log('check: ', keyCode, code, ev) + if (action) { + checked = ev.keyCode === action.key - while (action) { - if (now === 0) { - } else { - var _now = Date.now() - if (_now - now > 100) { - checked = false - break + if (idx > -1) { + if (now - _this.__TIME__ > 100) { + checked = false + } } - now = _now + if (checked) { + for (let k of action) { + checked = ev[`${k}Key`] + } + } + log(action, now, checked) } - action = actions.shift() - } - return checked - }, - fn: [callback] + return checked + }, + fn: [callback] + } } } - log(this.__EVENTS__) } } diff --git a/src/key.dict.es7 b/src/key.dict.es7 index c0a1afa..69a4262 100644 --- a/src/key.dict.es7 +++ b/src/key.dict.es7 @@ -3,9 +3,11 @@ export const MULTI_KEYS = { ctrl: 1, shift: 1, alt: 1, - super: 1 + meta: 1 } +export const MULTI_KEY_CODES = [16, 17, 18, 91] + // 按键对应的code值 export const KEY_DICT = { '0': 48, // Digit{N}, Numpad{N} @@ -62,7 +64,7 @@ export const KEY_DICT = { ctrl: 17, // ControlLeft, ControlRight alt: 18, // AltLeft, AltRight space: 32, - super: 91, // MetaLeft, MetaRight + meta: 91, // MetaLeft, MetaRight tab: 9, backspace: 8, numlock: 12,