TypeScript(TS) 自定义绑定快捷键

2024-08-30 21:52

本文主要是介绍TypeScript(TS) 自定义绑定快捷键,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 有很多软件中都可以让用户自定义快捷键

如微信中的快捷键:

思路:

1. 将快捷键分为两部分:

    a. 主要的键   'shift', 'ctrl', 'alt', 'command';

    b. 非主要的键  字母键、数字键等;

2. 键盘按下事件:比较按键和绑定的快捷键是否相同

 代码实现

/*** 快捷键信息对象*/
interface Shortcuts {// 快捷键readonly shortcut:string;// 名称readonly name: string;// 执行的方法readonly callback:Function,// 字母键readonly key: string,// 主组合键readonly modifiers: string[],
}const KEY_SHORTCUT = ['shift', 'ctrl', 'alt', 'command'];/*** 快捷键*/
export default class ShortcutBinder {// 存放快捷键信息的集合private readonly shortcuts:Shortcuts[];// 新快捷键  --->   默认快捷键private readonly defaultShortcutsMap: Map<string, string> = new Map<string, string>();private readonly defaultShortcuts:Shortcuts[];private static shortcutBinder:ShortcutBinder;// 单例public static getInstance(){if (!ShortcutBinder.shortcutBinder){ShortcutBinder.shortcutBinder = new ShortcutBinder()}return ShortcutBinder.shortcutBinder;}private constructor() {this.shortcuts = [];this.defaultShortcuts = [];// 初始化this.init();}private init() {this.addKeydownEvent();}/*** 添加快捷键*/private addKeydownEvent() {// 全局 键盘按下事件document.addEventListener('keydown', (event) => {console.log("按键:", event.keyCode, event.code, event.key)const modifers = getModifierKeysByKeyboardEvent(eventInfo.event);const matchedShortcut = this.shortcuts.find(shortcut =>// 判断字母按键是否相同checkKeyMatch(shortcut.key, event.key.toLowerCase()) &&// 判断非字母按键是否相同checkModifiersMatch(shortcut.modifiers, modifers));if (matchedShortcut !== undefined) {// 执行函数matchedShortcut.callback(event);}});}/*** 绑定默认快捷键和对应执行的方法* @param {string} shortcut* @param {Function} callback*/bind(shortcut:string, name:string, callback:Function) {this.addShortcut(shortcut, name, callback);// 存放默认快捷键this.defaultShortcutsMap.set(shortcut, shortcut);// 克隆默认快捷键this.defaultShortcuts.push(this.shortcuts[this.shortcuts.length-1])}/*** 修改绑定的快捷键* @param newShortcut 新组合键* @param oldShortcut 旧组合键*/editBind(newShortcut:string, oldShortcut:string){if (newShortcut === oldShortcut){// 新键和旧键一致 不做处理return;}let flag = false;// 获取快捷键let shortcutObj:Shortcuts|undefined = undefined;let len = this.shortcuts.length;// 当前位置let c = 0;for (let i = 0; i < len; i++) {if (oldShortcut === this.shortcuts[i].shortcut){shortcutObj = this.shortcuts[i];c = i;}if (newShortcut === this.shortcuts[i].shortcut){// 新快捷键与原有的冲突flag = true;}if (shortcutObj !== undefined && flag){break}}if (flag){// TODO 弹窗提示 快捷键冲突return;}if (shortcutObj === undefined){// TODO 弹窗提示没有该组合键return;}// 添加新的快捷键this.addShortcut(newShortcut, shortcutObj.name, shortcutObj.callback);// 删除原来的快捷键this.shortcuts.splice(c, 1);// 如果 旧快捷键 是默认键添加到映射let shortcutSlt = this.defaultShortcutsMap.get(oldShortcut);if (shortcutSlt !== undefined){// 删除原始的this.defaultShortcutsMap.delete(oldShortcut);// 添加新映射关系this.defaultShortcutsMap.set(newShortcut, shortcutSlt);}}/*** 重置绑定的快捷键* @param shortcut*/resettingBind(shortcut?:string){if (shortcut !== undefined){// 重置一个组合键let oldShortcut = this.defaultShortcutsMap.get(shortcut);if (oldShortcut !== undefined){this.editBind(oldShortcut, shortcut);}return;}// 重置所有组合键this.shortcuts.length = 0;this.defaultShortcuts.forEach(ds => {this.shortcuts.push(ds);})}/*** 获取快捷键集合*/getShortcuts(){return this.shortcuts;}/*** 添加绑定的快捷键* @param {string} shortcut 快捷键* @param {Function} callback 执行的方法*/private addShortcut(shortcut:string, name:string, callback:Function) {this.shortcuts.push({// 快捷键shortcut,// 名称name,// 执行的方法callback,// 字母按键 注意: 字母按键 不区分大小写但event.key区分大小写key: this.getKeyByShortcut(shortcut),// 主按键  'shift', 'ctrl', 'alt', 'command'modifiers: this.getModifiersByShortcut(shortcut),});}/*** 获取字母按键* @param {string} shortcut 快捷键的组合* @returns {string}*/private getKeyByShortcut(shortcut:string) {if (!shortcut.trim()) return '';let key = (shortcut.split('+').filter((key) => !KEY_SHORTCUT.includes(key.trim().toLowerCase()))[0] || '');return key.toLowerCase();}/*** 获取主按键 ['shift', 'ctrl', 'alt', 'command']* @param {string} shortcut 快捷键的组合* @returns {Array}*/private getModifiersByShortcut(shortcut:string) {const keys = shortcut.split('+').map((key) => key.trim().toLowerCase());let modifiers:string[] = [];keys.forEach((key) => {if (KEY_SHORTCUT.includes(key)) {modifiers.push(key);}});return modifiers;}
}/*** 统一主按键* @param {KeyboardEvent} event - keyboard event* @returns {Array}*/
const getModifierKeysByKeyboardEvent = (event:KeyboardEvent) => {const modifiers = [];if (event.shiftKey) {modifiers.push('shift');}if (event.altKey) {modifiers.push('alt');}if (event.ctrlKey) {modifiers.push('ctrl');}if (event.metaKey) {modifiers.push('command');}return modifiers;
};/*** 判断按下的非字母键是否相同* @param {Array} modifers1* @param {Array} modifers2* @returns {boolean}*/
function checkModifiersMatch(modifers1:string[], modifers2:string[]) {return modifers1.sort().join(',') === modifers2.sort().join(',');
}/*** 判断按下的 字母键 是否相同* @param {string} shortcutKey* @param {string} eventKey - event.key* @returns {boolean}*/
function checkKeyMatch(shortcutKey:string, eventKey:string) {return shortcutKey === eventKey;
}
 使用方式:
let shortcutBinder = ShortcutBinder.getInstance(this.editCore);// enter 菜单快捷键
shortcutBinder.bind('enter', "快速标记菜单",() => {console.log('enter');
});
shortcutBinder.bind('ctrl+s', '保存', () => {console.log('ctrl+s');
});
注意:

由于 event.key 区分受 shift 的影响,如:字母键区分大小写;

可以考虑 event.keyCode, event.code 来代替非主键('shift', 'ctrl', 'alt', 'command')

这篇关于TypeScript(TS) 自定义绑定快捷键的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1122033

相关文章

SpringBoot 自定义消息转换器使用详解

《SpringBoot自定义消息转换器使用详解》本文详细介绍了SpringBoot消息转换器的知识,并通过案例操作演示了如何进行自定义消息转换器的定制开发和使用,感兴趣的朋友一起看看吧... 目录一、前言二、SpringBoot 内容协商介绍2.1 什么是内容协商2.2 内容协商机制深入理解2.2.1 内容

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

自定义类型:结构体(续)

目录 一. 结构体的内存对齐 1.1 为什么存在内存对齐? 1.2 修改默认对齐数 二. 结构体传参 三. 结构体实现位段 一. 结构体的内存对齐 在前面的文章里我们已经讲过一部分的内存对齐的知识,并举出了两个例子,我们再举出两个例子继续说明: struct S3{double a;int b;char c;};int mian(){printf("%zd\n",s

键盘快捷键:提高工作效率与电脑操作的利器

键盘快捷键:提高工作效率与电脑操作的利器 在数字化时代,键盘快捷键成为了提高工作效率和优化电脑操作的重要工具。无论是日常办公、图像编辑、编程开发,还是游戏娱乐,掌握键盘快捷键都能带来极大的便利。本文将详细介绍键盘快捷键的概念、重要性、以及在不同应用场景中的具体应用。 什么是键盘快捷键? 键盘快捷键,也称为热键或快捷键,是指通过按下键盘上的一组键来完成特定命令或操作的方式。这些快捷键通常涉及同

Spring 源码解读:自定义实现Bean定义的注册与解析

引言 在Spring框架中,Bean的注册与解析是整个依赖注入流程的核心步骤。通过Bean定义,Spring容器知道如何创建、配置和管理每个Bean实例。本篇文章将通过实现一个简化版的Bean定义注册与解析机制,帮助你理解Spring框架背后的设计逻辑。我们还将对比Spring中的BeanDefinition和BeanDefinitionRegistry,以全面掌握Bean注册和解析的核心原理。

SpringMVC入参绑定特别注意

1.直接在controller中定义一个变量,但是此种传输方式有一个限制就是参数名和请求中的参数名必须保持一致,否则失效。 @RequestMapping("test2")@ResponseBodypublic DBHackResponse<UserInfoVo> test2(String id , String name){UserInfoVo userInfoVo = new UserInf

工作常用指令与快捷键

Git提交代码 git fetch  git add .  git commit -m “desc”  git pull  git push Git查看当前分支 git symbolic-ref --short -q HEAD Git创建新的分支并切换 git checkout -b XXXXXXXXXXXXXX git push origin XXXXXXXXXXXXXX

Oracle type (自定义类型的使用)

oracle - type   type定义: oracle中自定义数据类型 oracle中有基本的数据类型,如number,varchar2,date,numeric,float....但有时候我们需要特殊的格式, 如将name定义为(firstname,lastname)的形式,我们想把这个作为一个表的一列看待,这时候就要我们自己定义一个数据类型 格式 :create or repla

Maven(插件配置和生命周期的绑定)

1.这篇文章很好,介绍的maven插件的。 2.maven的source插件为例,可以把源代码打成包。 Goals Overview就可以查看该插件下面所有的目标。 这里我们要使用的是source:jar-no-fork。 3.查看source插件的example,然后配置到riil-collect.xml中。  <build>   <plugins>    <pl

HTML5自定义属性对象Dataset

原文转自HTML5自定义属性对象Dataset简介 一、html5 自定义属性介绍 之前翻译的“你必须知道的28个HTML5特征、窍门和技术”一文中对于HTML5中自定义合法属性data-已经做过些介绍,就是在HTML5中我们可以使用data-前缀设置我们需要的自定义属性,来进行一些数据的存放,例如我们要在一个文字按钮上存放相对应的id: <a href="javascript:" d