Markdown编辑器如何实时预览并保持滚动同步? Code°可欣 提问于 2026-03-13 14:53:18 阅读 77 组件 我用React写了个简单的Markdown编辑器,左边是textarea输入,右边用marked.parse()转成HTML预览。现在问题是:输入内容多了以后,两边滚动位置完全不一致,用户体验很差。 我试过监听textarea的scroll事件去同步右边容器的scrollTop,但右边是渲染后的HTML,高度和左边字符数没法直接对应,根本对不上。有没有靠谱的方案能实现类似Typora那种滚动同步效果? 我来解答 赞 14 收藏 分享 生成中... 手机扫码查看 复制链接 生成海报 反馈 发表解答 您需要先 登录/注册 才能发表解答 1 条解答 书生シ芳芳 Lv1 核心思路是用textarea当前光标位置的行号比例,去同步预览区的滚动位置。 代码实现: const MarkdownEditor = () => { const textareaRef = useRef(null); const previewRef = useRef(null); const isSyncing = useRef(false); // 获取光标所在的行号 const getCursorLineNumber = (textarea) => { const text = textarea.value.substring(0, textarea.selectionStart); return text.split('n').length; }; // 计算总行数 const getTotalLines = (text) => { return text.split('n').length; }; const handleScroll = () => { if (isSyncing.current) return; const textarea = textareaRef.current; const preview = previewRef.current; const cursorLine = getCursorLineNumber(textarea); const totalLines = getTotalLines(textarea.value); // 关键:用行号比例来同步,而不是直接用scrollTop const scrollRatio = (cursorLine - 1) / Math.max(totalLines - 1, 1); const maxScroll = preview.scrollHeight - preview.clientHeight; isSyncing.current = true; preview.scrollTop = scrollRatio * maxScroll; setTimeout(() => { isSyncing.current = false; }, 50); }; return ( ref={textareaRef} value={content} onChange={(e) => setContent(e.target.value)} onScroll={handleScroll} style={{ width: '50%', padding: '10px', fontFamily: 'monospace' }} /> ref={previewRef} style={{ width: '50%', padding: '10px', overflow: 'auto' }} dangerouslySetInnerHTML={{ __html: marked.parse(content) }} /> ); }; 这个方案比直接映射scrollTop靠谱,因为它是基于内容行号来算比例的,两边内容高度差异再大也能对上。 Typora内部也是类似的行号映射逻辑。 回复 点赞 2026-03-13 15:00 加载更多 相关推荐 2 回答 66 浏览 Markdown编辑器如何实时预览渲染效果? 我用Vue写了个简单的Markdown编辑器,但输入内容后没法实时看到HTML预览,试过用marked.js转换,但页面没更新。 我在methods里写了转换函数,绑定到textarea的input事... 长孙亚美 组件 2026-03-03 17:13:20 1 回答 62 浏览 Markdown 实时预览怎么实现双向同步? 我用 contenteditable 做了个 Markdown 编辑器,左边写源码右边实时预览,但改预览区内容没法同步回源码区,这咋整? 试过监听 input 事件,但预览区是渲染后的 HTML,转回... 永莲🍀 交互 2026-03-14 22:16:21 1 回答 31 浏览 Markdown 实时预览怎么实现双向同步? 我在做一个 Markdown 编辑器,左边是输入框,右边是预览区。现在的问题是:我改了左边内容,右边能实时更新;但用户点击右边预览里的某个段落,没法自动定位到左边对应位置。这双向同步到底咋搞啊? 试过... 迷人的天佑 交互 2026-03-02 20:24:20 1 回答 34 浏览 Markdown 实时预览时怎么避免频繁解析导致卡顿? 我正在做一个支持 Markdown 的富文本编辑器,左边是输入框,右边是实时预览。但每次用户输入就立刻调用解析函数,内容一多页面就明显卡顿。 试过用 lodash.debounce 延迟解析,但延迟太... 书生シ克培 交互 2026-03-24 10:52:18 2 回答 47 浏览 Markdown编辑器内容无法实时预览怎么办? 我用React写了个简单的Markdown编辑器,输入框的内容变了,但预览区完全没反应,是不是状态没绑对? 试过用useState存markdown字符串,也加了onChange监听,可右边的预览就是... FSD-文科 组件 2026-03-21 11:21:17 2 回答 48 浏览 Markdown编辑器如何实现代码块高亮并保留缩进? 我在用Vue项目集成Markdown编辑器时卡住了。用了marked库渲染,代码块能显示但没有高亮,手动引入highlight.js后虽然能高亮了,但输入的缩进会被浏览器自动压缩成一个空格,代码看起来... 司徒心虹 组件 2026-02-11 09:04:57 1 回答 36 浏览 Markdown富文本编辑器中代码块样式为啥不生效? 我用了一个开源的Markdown编辑器组件,渲染出来的代码块样式完全不对,明明写了CSS但没效果。是不是scoped样式的问题?还是编辑器内部用了shadow DOM? 我试过在全局样式里加规则,也试... 程序员素香 组件 2026-03-31 11:13:15 2 回答 61 浏览 Markdown编辑器上传图片后路径显示404怎么办? 在用Quill.js实现Markdown编辑器时,用户上传图片用FileSaver保存为base64格式,但渲染后图片路径显示404错误。明明保存成功了啊,控制台提示GET blob:null/xxx... 宇文世杰 交互 2026-02-15 15:39:27 2 回答 114 浏览 Markdown编辑器中代码块样式被主题CSS覆盖怎么办? 我在开发Markdown编辑器时遇到了样式冲突问题,切换主题后代码块的背景色和边框总是被主题CSS覆盖。试过给代码块类加!important都没用。 比如我写了这样的CSS: .code-block ... 芸硕酱~ 交互 2026-01-30 02:36:42 2 回答 126 浏览 Markdown图片语法在富文本编辑器里显示为文本怎么办? 在用markdown-it实现富文本编辑器时,输入图片语法,但预览区只显示原始文本而没渲染成图片。检查过插件是否加载,确认已引入... 司徒金梅 组件 2026-01-29 11:21:36
代码实现:
这个方案比直接映射scrollTop靠谱,因为它是基于内容行号来算比例的,两边内容高度差异再大也能对上。 Typora内部也是类似的行号映射逻辑。