UNPKG

ahooks

Version:
293 lines (292 loc) 9.73 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _useLatest = _interopRequireDefault(require("../useLatest")); var _utils = require("../utils"); var _domTarget = require("../utils/domTarget"); var _useDeepCompareWithTarget = _interopRequireDefault(require("../utils/useDeepCompareWithTarget")); var _isAppleDevice = _interopRequireDefault(require("../utils/isAppleDevice")); function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } // 键盘事件 keyCode 别名 var aliasKeyCodeMap = { '0': 48, '1': 49, '2': 50, '3': 51, '4': 52, '5': 53, '6': 54, '7': 55, '8': 56, '9': 57, backspace: 8, tab: 9, enter: 13, shift: 16, // Legacy alias kept for compatibility; standard name is "control". ctrl: 17, control: 17, alt: 18, // Legacy alias kept for compatibility; standard name is "pause". pausebreak: 19, pause: 19, capslock: 20, // Legacy alias kept for compatibility; standard name is "escape". esc: 27, escape: 27, // Legacy alias kept for compatibility; standard name is "spacebar" (non-standard but widely used). space: 32, spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36, // Legacy aliases kept for compatibility; standard names are "arrowleft/arrowup/arrowright/arrowdown". leftarrow: 37, arrowleft: 37, uparrow: 38, arrowup: 38, rightarrow: 39, arrowright: 39, downarrow: 40, arrowdown: 40, insert: 45, "delete": 46, a: 65, b: 66, c: 67, d: 68, e: 69, f: 70, g: 71, h: 72, i: 73, j: 74, k: 75, l: 76, m: 77, n: 78, o: 79, p: 80, q: 81, r: 82, s: 83, t: 84, u: 85, v: 86, w: 87, x: 88, y: 89, z: 90, leftwindowkey: 91, rightwindowkey: 92, meta: _isAppleDevice["default"] ? [91, 93] : [91, 92], // Legacy alias kept for compatibility; standard name is "contextmenu". selectkey: 93, contextmenu: 93, numpad0: 96, numpad1: 97, numpad2: 98, numpad3: 99, numpad4: 100, numpad5: 101, numpad6: 102, numpad7: 103, numpad8: 104, numpad9: 105, multiply: 106, add: 107, subtract: 109, decimalpoint: 110, divide: 111, f1: 112, f2: 113, f3: 114, f4: 115, f5: 116, f6: 117, f7: 118, f8: 119, f9: 120, f10: 121, f11: 122, f12: 123, numlock: 144, scrolllock: 145, semicolon: 186, equalsign: 187, comma: 188, dash: 189, period: 190, forwardslash: 191, graveaccent: 192, openbracket: 219, backslash: 220, closebracket: 221, singlequote: 222 }; // 修饰键 var modifierKey = { ctrl: function ctrl(event) { return event.ctrlKey || event.type === 'keyup' && event.keyCode === 17; }, shift: function shift(event) { return event.shiftKey || event.type === 'keyup' && event.keyCode === 16; }, alt: function alt(event) { return event.altKey || event.type === 'keyup' && event.keyCode === 18; }, meta: function meta(event) { return event.metaKey || event.type === 'keyup' && aliasKeyCodeMap.meta.includes(event.keyCode); } }; // 判断合法的按键类型 function isValidKeyType(value) { return (0, _utils.isString)(value) || (0, _utils.isNumber)(value); } // 根据 event 计算激活键数量 function countKeyByEvent(event) { var countOfModifier = Object.keys(modifierKey).reduce(function (total, key) { if (modifierKey[key](event)) { return total + 1; } return total; }, 0); // 16 17 18 91 92 是修饰键的 keyCode,如果 keyCode 是修饰键,那么激活数量就是修饰键的数量,如果不是,那么就需要 +1 return [16, 17, 18, 91, 92].includes(event.keyCode) ? countOfModifier : countOfModifier + 1; } /** * 判断按键是否激活 * @param [event: KeyboardEvent]键盘事件 * @param [keyFilter: any] 当前键 * @returns string | number | boolean */ function genFilterKey(event, keyFilter, exactMatch) { // 浏览器自动补全 input 的时候,会触发 keyDown、keyUp 事件,但此时 event.key 等为空 if (!event.key) { return false; } // 数字类型直接匹配事件的 keyCode if ((0, _utils.isNumber)(keyFilter)) { return event.keyCode === keyFilter ? keyFilter : false; } // 字符串依次判断是否有组合键 var genArr = keyFilter.split('.'); var genLen = 0; var _iterator = _createForOfIteratorHelper(genArr), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var key = _step.value; // 组合键 var genModifier = modifierKey[key]; // keyCode 别名 var aliasKeyCode = aliasKeyCodeMap[key.toLowerCase()]; if (genModifier && genModifier(event) || aliasKeyCode && aliasKeyCode === event.keyCode) { genLen++; } } /** * 需要判断触发的键位和监听的键位完全一致,判断方法就是触发的键位里有且等于监听的键位 * genLen === genArr.length 能判断出来触发的键位里有监听的键位 * countKeyByEvent(event) === genArr.length 判断出来触发的键位数量里有且等于监听的键位数量 * 主要用来防止按组合键其子集也会触发的情况,例如监听 ctrl+a 会触发监听 ctrl 和 a 两个键的事件。 */ } catch (err) { _iterator.e(err); } finally { _iterator.f(); } if (exactMatch) { return genLen === genArr.length && countKeyByEvent(event) === genArr.length ? keyFilter : false; } return genLen === genArr.length ? keyFilter : false; } /** * 键盘输入预处理方法 * @param [keyFilter: any] 当前键 * @returns () => Boolean */ function genKeyFormatter(keyFilter, exactMatch) { if ((0, _utils.isFunction)(keyFilter)) { return keyFilter; } if (isValidKeyType(keyFilter)) { return function (event) { return genFilterKey(event, keyFilter, exactMatch); }; } if (Array.isArray(keyFilter)) { return function (event) { return keyFilter.find(function (item) { return genFilterKey(event, item, exactMatch); }); }; } return function () { return Boolean(keyFilter); }; } var defaultEvents = ['keydown']; function useKeyPress(keyFilter, eventHandler, option) { var _ref = option || {}, _ref$events = _ref.events, events = _ref$events === void 0 ? defaultEvents : _ref$events, target = _ref.target, _ref$exactMatch = _ref.exactMatch, exactMatch = _ref$exactMatch === void 0 ? false : _ref$exactMatch, _ref$useCapture = _ref.useCapture, useCapture = _ref$useCapture === void 0 ? false : _ref$useCapture; var eventHandlerRef = (0, _useLatest["default"])(eventHandler); var keyFilterRef = (0, _useLatest["default"])(keyFilter); (0, _useDeepCompareWithTarget["default"])(function () { var _a; var el = (0, _domTarget.getTargetElement)(target, window); if (!el) { return; } var callbackHandler = function callbackHandler(event) { var _a; var keyEvent = event; var genGuard = genKeyFormatter(keyFilterRef.current, exactMatch); var keyGuard = genGuard(keyEvent); var firedKey = isValidKeyType(keyGuard) ? keyGuard : keyEvent.key; if (keyGuard) { return (_a = eventHandlerRef.current) === null || _a === void 0 ? void 0 : _a.call(eventHandlerRef, keyEvent, firedKey); } }; var _iterator2 = _createForOfIteratorHelper(events), _step2; try { for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { var eventName = _step2.value; (_a = el === null || el === void 0 ? void 0 : el.addEventListener) === null || _a === void 0 ? void 0 : _a.call(el, eventName, callbackHandler, useCapture); } } catch (err) { _iterator2.e(err); } finally { _iterator2.f(); } return function () { var _a; var _iterator3 = _createForOfIteratorHelper(events), _step3; try { for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { var eventName = _step3.value; (_a = el === null || el === void 0 ? void 0 : el.removeEventListener) === null || _a === void 0 ? void 0 : _a.call(el, eventName, callbackHandler, useCapture); } } catch (err) { _iterator3.e(err); } finally { _iterator3.f(); } }; }, [events], target); } var _default = exports["default"] = useKeyPress;