尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

react-md-editor深度揭秘:CodeMirror的getTokenAt如何实现光标格式智能检测

react-md-editor深度揭秘:CodeMirror的getTokenAt如何实现光标格式智能检测 react-md-editor深度揭秘CodeMirror的getTokenAt如何实现光标格式智能检测【免费下载链接】react-md-editorReact.js Markdown Editor Component项目地址: https://gitcode.com/gh_mirrors/rea/react-md-editorreact-md-editor 是一个基于 React 和 CodeMirror 构建的 Markdown 编辑器组件它的杀手锏是用 CodeMirror 的getTokenAtAPI 实现光标位置格式的智能检测——当你的光标停留在加粗文本或标题行上时工具栏对应的按钮会自动按下高亮。这篇文章将带你读懂这套机制背后的完整原理。为什么光标格式检测对 Markdown 编辑器很重要 在 Markdown 编辑器中用户点击加粗按钮通常有两种期望光标不在加粗文本上 →应用加粗格式光标已经在加粗文本上 →移除加粗格式要让编辑器知道光标当前处于什么格式最可靠的方式不是自己解析文本而是借助 CodeMirror 的 Markdown 语法高亮引擎——它本来就把文本切分成带类型标记的tokengetTokenAt只是把光标所在位置的 token 类型交给你。react-md-editor 正是这样做的整个链路只涉及两个核心文件src/MDEditor.js—— 编辑器组件主体负责事件监听与工具栏渲染src/format.js—— 格式定义、光标状态检测与格式应用逻辑第一步监听光标活动实时获取格式状态在src/MDEditor.js中组件挂载时会注册cursorActivity事件this.codeMirror.on(cursorActivity, this.updateCursorState);每次光标移动或选区变化updateCursorState都会调用getCursorState重新计算状态并触发渲染。这是按钮状态实时跟随光标的关键逻辑极简但非常有效。getTokenAt 返回的到底是什么getCursorState的核心只有两行位于src/format.jsvar token cs.token cm.getTokenAt(pos); var tokens token.type.split( );CodeMirror 的 markdown 模式会给每段文本打上 CSS 风格类名。例如**bold**会标成strong# 标题会标成header-1。getTokenAt返回的 token 对象中type字段就是这些类名空格分隔于是检测格式变成了读类名这一件简单事。从 token 类型到格式状态的映射表src/format.js开头定义了一张格式表是理解整个项目的钥匙const FORMATS { h1: { type: block, token: header-1, before: #, re: /^#\s/ }, bold: { type: inline, token: strong, before: **, after: ** }, italic: { type: inline, token: em, before: _, after: _ }, quote: { type: block, token: quote, re: /^\\s/ }, oList: { type: block, re: /^\d\.\s/ }, uList: { type: block, re: /^[\*\-]\s/ }, // ... };每个格式记录了三个关键信息tokenCodeMirror 高亮类名用于检测before / after插入格式用的包裹符号用于应用re行首正则用于移除格式。检测逻辑再建一张反向索引FORMAT_TOKENSstrong → bold、header-1 → h1遍历光标 token 类型逐条查表即可。两个精巧的特殊判断检测逻辑中有两处细节值得新手学习链接的区分link类型标记链接文字string类型标记链接地址两者都映射为link方便后续扩展链接按钮。列表的消歧有序和无序列表在 markdown 模式下 token 类型都是variable-2无法直接区分。代码于是取回当前行文本用正则^\s*\d\.\s判断行首是否是数字. 是则为有序列表否则为无序列表。这种token 不够正则来补的思路非常实用。工具栏按钮的按下状态是怎么来的 ✨检测到的状态存放在组件 state 的cs字段中。渲染按钮时renderButton会把状态注入 CSS 类名var className classNames(MDEditor_toolbarButton, { MDEditor_toolbarButton--pressed: this.state.cs[formatKey] });对应样式在less/component.less中定义了--pressed的深色背景和内阴影视觉上模拟真实按钮的按压效果。至此完整闭环是光标移动 →cursorActivity事件 →getTokenAt读取 token → 查表得到格式状态 → React 重新渲染 → 按钮高亮一键应用 / 智能移除格式点击按钮后调用applyFormat它再次检测光标状态自动决定执行应用还是移除var cs getCursorState(cm); operations[format.type (cs[key] ? Remove : Apply)](cm, format);operations对象提供了四种操作操作行为inlineApply选区两侧包上**或_并把选区调整回原文inlineRemove反向扫描行文本找到包裹符号并剥离blockApply行首插入#、等前缀空行自动填占位文字blockRemove用格式表中的re正则去掉行首前缀块级格式标题、引用、列表只操作当前行首行内格式加粗、斜体操作选区这种按type分发的设计让代码保持得相当干净。本地运行示例三步上手指南想亲手体验效果只需克隆仓库git clone https://gitcode.com/gh_mirrors/rea/react-md-editor安装依赖npm install启动示例npm start然后打开localhost:8000示例代码在example/src/example.js右侧用marked做了实时预览。试着把光标移入预置的**bold**文本你会看到工具栏的b按钮立刻变为按下状态——那就是getTokenAt在工作。小结react-md-editor 用不到 100 行代码src/format.js就实现了智能光标格式检测 一键切换格式核心启示有三点复用编辑器引擎的语法分析比手写正则解析全文更可靠、更省事token 类型到业务格式的映射表让检测、应用、移除三者共用一份定义事件驱动 状态渲染光标一动、UI 即变天然契合 React 的数据流。如果你想给自己的编辑器加类似功能从这张FORMATS映射表和cursorActivity监听入手就是最短路径。【免费下载链接】react-md-editorReact.js Markdown Editor Component项目地址: https://gitcode.com/gh_mirrors/rea/react-md-editor创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表