第三步:编辑体验升级——实现双向同步与光标定位
一、前置准备:理解双向同步与光标定位的核心挑战 在构建现代化 Markdown 编辑器(如 Obsidian 风格、Typora 体验或 VS Code 插件)时,「所见即所得」早已不是单向渲染的终点——用户期待的是编辑源码时预览实时响应,点击预览又能精准跳转回对应源码位置。这背后依赖两大支柱:双向同步与光标定位映射。 双向同步 ≠ 单向渲染:它指编辑器内容变更 → 触发 AST 解析 → 更新预览;同时,用户在预览中点击某段落 → 反查源码偏移量 → 移动编辑器光标。二者构成闭环,任何一方缺失都会导致体验断裂。 光标定位 ≠ 简单行号对齐:Markdown 源码(纯文本)与 HTML 渲染结果(嵌套 DOM 树)之间不存在天然的一一对应关系。一个 ## 标题 在源码占 1 行、3 字符,在渲染后可能生成 <h2> + 文本节点 + 段前间距,其 DOM 位置无法通过行号直接推算。 对比维度 传统单向预览(如早期 StackEdit) 双向同步编辑器(如 Typora / Obsidian Live Preview) 用户操作流 编辑 → 手动刷新/切换标签页 → 查看效果 编辑时预览自动更新;点击预览任意位置 → 光标瞬移至源码对应行 光标反馈 无交互反馈,预览仅作“快照” 预览高亮当前编辑段落;选区跨界面同步;滚动联动 技术复杂度 低(remark-parse + remark-rehype + hast-util-to-html 即可) 高(需位置追踪、防死循环、DOM ↔ Offset 双向映射、事务隔离) 安全前提 无特殊限制 ✅ 必须设置预览容器 contenteditable="false",禁用所有用户输入事件,防止 DOM 直接修改污染源码状态 关键技术选型依据如下: ...