ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

canvas-editor 自定义快捷键开发指南:从 KeyMap 注册到全局/编辑器级事件分发

canvas-editor 自定义快捷键开发指南:从 KeyMap 注册到全局/编辑器级事件分发 前端UI组件富文本【免费下载链接】canvas-editorA Canvas/SVG-based rich text editor项目地址https://gitcode.com/gh_mirrors/ca/canvas-editor点击查看免费下载本文聚焦 canvas-editor一个基于 Canvas/SVG 的富文本编辑器的快捷键扩展机制讲解如何通过instance.register.shortcutList注册自定义快捷键、理解IRegisterShortcut各字段mod、isGlobal、disable等的语义与平台差异并结合 Shortcut.ts 的源码说明内部快捷键表、事件绑定与匹配分发流程让读者能基于此为编辑器定制完整可用的快捷键方案。如何注册自定义快捷键基础用法canvas-editor 的注册入口统一由Register模块暴露。创建编辑器实例后通过instance.register.shortcutList([...])即可批量注入自定义快捷键import Editor from hufe921/canvas-editor const instance new Editor(container, IElement[]data, options) instance.register.shortcutList([ { key: KeyMap; ctrl?: boolean; meta?: boolean; mod?: boolean; // windows:ctrl || mac:command shift?: boolean; alt?: boolean; isGlobal?: boolean; callback?: (command: Command) any; disable?: boolean; } ])其中key为必填取值为KeyMap枚举ctrl、meta、mod、shift、alt、isGlobal、disable、callback均为可选项一个调用可以传入多条快捷键配置编辑器会按注册顺序逐一匹配。从源码结构看Register.shortcutList只是对Shortcut.registerShortcutList的绑定转发见 Register.ts实际执行逻辑由 Shortcut.ts 中的registerShortcutList完成public registerShortcutList(payload: IRegisterShortcut[]) { this._addShortcutList(payload) }完整可运行示例以下示例注册一个「Ctrl/Cmd K」插入超链接的快捷键假设数据中已存在待选中的超链接文本同时注册一个全局可用的「Ctrl/Cmd H」聚焦搜索框的快捷键import Editor, { KeyMap } from hufe921/canvas-editor const instance new Editor(container, data, options) instance.register.shortcutList([ { key: KeyMap.K, mod: true, callback: (command) { command.executeHyperlink() } }, { key: KeyMap.H, mod: true, isGlobal: true, callback: (command) { command.executeFocus() } } ])command是 Command 实例其暴露了丰富的executeXxx命令方法如executeBold、executeItalic、executeTitle等自定义快捷键的回调可直接调用这些命令或编写任意自定义逻辑。IRegisterShortcut 配置项详解接口定义位于 src/editor/interface/shortcut/Shortcut.tsexport interface IRegisterShortcut { key: KeyMap ctrl?: boolean meta?: boolean mod?: boolean // windows:ctrl || mac:command shift?: boolean alt?: boolean // windows:alt || mac:option isGlobal?: boolean callback?: (command: Command) void disable?: boolean }字段类型必填说明keyKeyMap是要匹配的按键取自KeyMap枚举ctrlboolean否要求按下 Ctrl 键metaboolean否要求按下 MetaMac 的 Command键modboolean否跨平台修饰键Windows 上等价于 ctrlMac 上等价于 commandshiftboolean否要求按下 Shift 键altboolean否要求按下 Alt 键Mac 上为 OptionisGlobalboolean否是否为全局快捷键不依赖编辑器焦点callback(command: Command) void否命中快捷键后的回调接收Command实例disableboolean否是否禁用该快捷键key 的取值KeyMap 枚举key的类型是KeyMap枚举定义于 src/editor/dataset/enum/KeyMap.ts。它同时覆盖了功能键、方向键、标点与字母数字键功能键Delete、Backspace、Enter、Escape、Tab、Home、End、Alt、Meta方向键LeftArrowLeft、RightArrowRight、UpArrowUp、DownArrowDown标点[、]、,、.、、、、-、字母AZ小写az以及A_UPPERCASEZ_UPPERCASE大写AZ数字ZERONINE09。export enum KeyMap { Delete Delete, Backspace Backspace, Enter Enter, Left ArrowLeft, Right ArrowRight, Up ArrowUp, Down ArrowDown, ESC Escape, TAB Tab, LEFT_BRACKET [, RIGHT_BRACKET ], COMMA ,, PERIOD ., LEFT_ANGLE_BRACKET , RIGHT_ANGLE_BRACKET , A a, B b, // ... A_UPPERCASE ~ Z_UPPERCASE, ZERO ~ NINE }注册时建议使用枚举成员而非裸字符串例如KeyMap.B而不是b以便获得类型提示与拼写校验。修饰键语义与平台差异mod 与 ctrl / meta 的关系mod: true表示「Windows 上按 CtrlmacOS 上按 Command」由 hotkey.ts 中的isMod工具函数实现import { isApple } from ./ua export function isMod(evt: KeyboardEvent | MouseEvent) { return isApple ? evt.metaKey : evt.ctrlKey }isApple通过navigator.userAgent中的Mac OS X判断当前是否为 macOS见 ua.ts。alt: true在 Mac 上对应 Option 键altKey字段注释为windows:alt || mac:option。因此如果希望快捷键在 Windows 与 macOS 上行为一致应优先使用mod如果只想监听某个平台特有的组合键则分别使用ctrl或meta。匹配逻辑源码级Shortcut._execute是按键匹配的核心Shortcut.tsprivate _execute(evt: KeyboardEvent, shortCutList: IRegisterShortcut[]) { for (let s 0; s shortCutList.length; s) { const shortCut shortCutList[s] if ( (shortCut.mod ? isMod(evt) !!shortCut.mod : evt.ctrlKey !!shortCut.ctrl evt.metaKey !!shortCut.meta) evt.shiftKey !!shortCut.shift evt.altKey !!shortCut.alt evt.key.toLowerCase() shortCut.key.toLowerCase() ) { if (!shortCut.disable) { shortCut?.callback?.(this.command) evt.preventDefault() } break } } }匹配规则要点组合修饰键shift、alt必须与事件中的shiftKey、altKey严格相等即配置为true时要求按下配置为false/缺省时要求未按下mod 优先配置了mod时走isMod(evt)判断未配置mod时ctrl与meta分别对应ctrlKey与metaKey按键大小写不敏感evt.key.toLowerCase() shortCut.key.toLowerCase()因此注册KeyMap.B大写或KeyMap.b小写都能命中B键首个命中即中断快捷键列表按注册顺序遍历命中第一条即break不再继续匹配后续项。因此若两条配置存在冲突先注册的优先命中即拦截callback执行后调用evt.preventDefault()阻止浏览器默认行为例如阻止 CtrlB 触发浏览器加粗/收藏等disable 语义当disable: true时该条快捷键被跳过不执行但仍然会中断遍历break依然执行。利用这一特性可以用disable覆盖内部快捷键的默认行为。isGlobal全局快捷键与编辑器快捷键Shortcut在构造时会把快捷键表拆分为两个列表Shortcut.tsprivate _addShortcutList(payload: IRegisterShortcut[]) { for (let s payload.length - 1; s 0; s--) { const shortCut payload[s] if (shortCut.isGlobal) { this.globalShortcutList.unshift(shortCut) } else { this.agentShortcutList.unshift(shortCut) } } }两个列表分别绑定在两类事件源上全局快捷键globalShortcutList通过document.addEventListener(keydown, this._globalKeydown)绑定在document上Shortcut.ts。无论焦点是否在编辑器内都会触发编辑器快捷键agentShortcutList通过光标代理 DOMdraw.getCursor().getAgentDom()的keydown事件触发Shortcut.ts。仅当编辑器获得焦点光标代理处于活动状态时生效。使用建议需要「无论焦点在何处都响应的快捷键」如呼出搜索框、切换主题、保存草稿→ 设置isGlobal: true只在编辑文本时生效的快捷键如加粗、标题→ 保持默认isGlobal: false注意全局快捷键会注册在document上编辑器的removeEvent()会移除该监听销毁实例时应调用清理方法以免事件泄漏。快捷键注册机制与内部快捷键注册转发链路Register.ts 将快捷键注册方法绑定到实例上形成instance.register.shortcutList(...)的调用链this.shortcutList shortcut.registerShortcutList.bind(shortcut)外部注册的快捷键通过_addShortcutList与内置快捷键一同进入全局/编辑器两个列表无需额外配置即参与同一套匹配与分发流程。内置快捷键表编辑器内置了三组快捷键表均在 Shortcut.ts 构造时注入this._addShortcutList([...richtextKeys, ...titleKeys, ...listKeys])richtextKeys富文本格式类快捷键如mod [/mod ]增大/减小字号、mod B加粗、mod I斜体、mod U下划线、mod L/E/R/J左/中/右/两端对齐、mod Shift J分散对齐、Ctrl Shift X删除线等。其中上下标的按键做了平台适配isApple ? KeyMap.COMMA : KeyMap.RIGHT_ANGLE_BRACKETtitleKeys标题类快捷键Ctrl Alt 0~6分别对应正文与 H1~H6回调调用command.executeTitle(...)listKeys列表类快捷键mod Shift I无序列表、mod Shift U有序列表。完整的内部快捷键清单可参考 shortcut-internal.md如Ctrl/Cmd Z撤销、Ctrl/Cmd Y重做、Ctrl/Cmd C/X/A复制/剪切/全选、Ctrl/Cmd S保存、方向键与Shift 方向键选区缩放、Esc退出格式刷、Tab/Shift Tab缩进与控件切换等。测试验证仓库为快捷键模块提供了单元测试 tests/core/shortcut/Shortcut.test.ts其中验证了「注册自定义快捷键不抛异常」的核心行为it(registerShortcutList 注册自定义快捷键, () { ctx createTestEditor() const callback vi.fn() const shortcutList [ { key: k, mod: true, shift: false, alt: false, ctrl: false, meta: false, isGlobal: false, disable: false, callback } ] expect(() { ctx.editor.command.executeFocus() ctx.editor.use((_editor, options) { options?.register?.shortcutList?.(shortcutList) }) }).not.toThrow() })测试通过createTestEditor()创建真实编辑器实例在获得焦点后通过instance.use(...)注册快捷键验证注册流程的健壮性。这同时也展示了另一种注册时机在插件/扩展的use钩子中通过options.register.shortcutList注入快捷键。实践建议优先使用mod而不是分别指定ctrl/meta保证跨平台体验一致避免与内置快捷键冲突先查阅 shortcut-internal.md 的默认表若确需覆盖可注册同键位配置并利用「先注册先命中」的规则或借助disable: true禁用内置项注意禁用项也会中断匹配区分全局与编辑器内快捷键isGlobal: true的快捷键在编辑器失焦时也会响应请谨慎使用避免影响页面其他交互回调尽量使用Command的executeXxx命令以保持与撤销/重做历史、数据模型的一致性大小写统一匹配对大小写不敏感但建议统一使用KeyMap枚举便于维护与类型检查。相关文档内部快捷键完整清单docs/en/guide/shortcut-internal.md快捷键接口定义src/editor/interface/shortcut/Shortcut.ts快捷键核心实现src/editor/core/shortcut/Shortcut.ts内部快捷键表src/editor/core/shortcut/keys/richtextKeys.ts、src/editor/core/shortcut/keys/titleKeys.ts、src/editor/core/shortcut/keys/listKeys.ts快捷键模块测试tests/core/shortcut/Shortcut.test.ts赞分享前端UI组件富文本【免费下载链接】canvas-editorA Canvas/SVG-based rich text editor项目地址https://gitcode.com/gh_mirrors/ca/canvas-editor点击查看免费下载相关推荐canvas-editor 自定义快捷键完全指南从注册 API 到 Command 回调的实战解析canvas editor 自定义快捷键完全指南从注册 API 到 Command 回调的实战解析 导读 在 canvas editor一个基于 Canva前端UI组件富文本canvas-editor扩展开发从零开始构建自定义编辑器组件canvas editor扩展开发从零开始构建自定义编辑器组件 canvas editor是一款基于Canvas/SVG技术的富文本编辑器为开发者提供了强大前端UI组件富文本Nullboard自定义快捷键开发从事件监听到底层逻辑实现Nullboard自定义快捷键开发从事件监听到底层逻辑实现 你是否经常在使用Nullboard看板时因为频繁的鼠标操作而感到效率低下是否希望通过键盘快捷键上一篇PostHog 安全审计 Skill面向 SaaS 多租户系统的校准式 AI 安全审计工作流下一篇用 GitHub 环境教学ML-For-Beginners 机器学习课程的课堂部署与运营指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表