可行且轻量,但需注意dom更新频率、xss风险(marked必须开启sanitize或用dompurify)、滚动锚点偏移(需比例映射scrolltop)及样式错乱(应引入github-markdown-css或手动重置)。

直接用原生 HTML + JavaScript 实现 Markdown 实时编辑预览,不依赖大型框架(如 React/Vue),核心靠 marked 解析 + 双栏同步滚动,可行且轻量;但要注意 DOM 更新频率、XSS 风险和滚动锚点偏移这三处最容易翻车的地方。
用 marked 解析 Markdown 时必须开启 sanitize: true
默认 marked 不过滤 HTML 标签,用户输入 <script>alert(1)</script> 会直接执行。即使你只做内部工具,也建议强制开启安全模式:
marked.setOptions({
sanitize: true,
// ⚠️ 注意:v4+ 版本改用 sanitizer 选项,但最简方案仍是 sanitize: true
});
如果你用的是 marked@^4.0.0,sanitize 已废弃,应改用 renderer + 自定义 html 方法拦截,或搭配 DOMPurify 二次处理 —— 否则任何含 <iframe></iframe>、<img onerror="..."> 的输入都可能触发 XSS。
textarea 和预览区滚动不同步?用 scrollHeight 和 scrollTop 做比例映射
纯 CSS 无法让两个容器滚动联动,必须监听 scroll 或 input 事件手动同步。常见错误是直接复制 scrollTop 值,导致预览区滚动过快或卡顿:
- 编辑区高度变化频繁(比如输入换行、粘贴大段文本),
scrollHeight会抖动,需节流处理 - 预览区内容渲染有延迟,应在
marked.parse()回调后才更新scrollTop - 比例计算要用
(textarea.scrollTop / (textarea.scrollHeight - textarea.clientHeight)),再乘以预览区可滚动高度
示例关键逻辑:
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
textarea.addEventListener('scroll', () => {
const ratio = textarea.scrollTop / (textarea.scrollHeight - textarea.clientHeight);
preview.scrollTop = ratio * (preview.scrollHeight - preview.clientHeight);
});
为什么预览区样式错乱?别漏掉 marked 输出的 <p></p> 和 <code> 默认样式
marked 输出的是纯语义 HTML(如无 class 的 <h2></h2>、<pre class="brush:php;toolbar:false;"><code></code>),浏览器默认样式和你的页面主题冲突很常见:</pre>
<pre class="brush:php;toolbar:false;"><code></code> 没加语法高亮 → 推荐用 <code>highlight.js</code> 的 <code>highlightElement()</code> 在渲染后调用</pre><table> 无边框/错位 → 需手动重置 <code>border-collapse: collapse和td, thpadding- 链接没下划线或颜色太浅 → 至少加一条
preview a { color: #007bff; text-decoration: underline; }
最省事的做法:给预览容器加 class="markdown-body",然后引入 GitHub 官方的 github-markdown-css(注意只用它对 block 元素的 reset 规则,别全量加载)。
滚动同步的精度、HTML 渲染的安全边界、样式隔离的粒度——这三点在小项目里容易被当成“先跑起来再说”的环节,但一旦用户开始粘贴代码块或嵌入表格,问题就会集中爆发。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










