Markdown 在线预览器

实时分屏预览:左侧编辑 Markdown,右侧即时渲染 HTML。配 16 个工具栏快捷按钮、双向同步滚动、 字数统计、阅读时间估算、HTML 导出与草稿自动保存。手写轻量 GFM 子集解析器, 零依赖、默认 HTML 转义防 XSS,所有解析在浏览器本地完成。

字符 0字数 0行数 0预计阅读 1 分钟

预览区为空,请在左侧输入 Markdown。

常见问题

支持哪些 Markdown 语法?

本工具实现了 GFM(GitHub Flavored Markdown)子集,覆盖以下语法:

  • 标题:H1 ~ H6(# ~ ######),自动生成锚点 id
  • 段落:空行分隔段落,段内单换行保留为 <br>
  • 粗体**text**__text__
  • 斜体*text*_text_
  • 删除线~~text~~
  • 行内代码`code`(支持多反引号包裹含反引号内容)
  • 代码块:三反引号围栏 ```lang,支持语言标识
  • 链接[text](url "title"),自动加 target="_blank"rel="noopener noreferrer"
  • 图片![alt](url "title"),自动加 loading="lazy"
  • 自动链接<https://example.com><user@example.com>
  • 无序列表- / * / +
  • 有序列表1.(数字 + 点)
  • 任务列表- [ ] 未完成、- [x] 已完成
  • 引用> text,支持引用内嵌套标题与列表
  • 表格:管道符分隔,第二行 ---|:---|---:|:---: 控制对齐(左/右/中/默认)
  • 水平线--- / *** / ___

未实现的进阶语法:脚注、定义列表、数学公式、Mermaid 图表、TOC 目录、自定义锚点。如有需要可在反馈渠道提出。

为什么不引入 marked / markdown-it 等成熟库?

三个核心考虑:

  1. bundle 体积可控:marked 约 30KB(gzip 10KB)+ DOMPurify 约 25KB(gzip 9KB)共 60KB, 而手写解析器仅约 14KB(gzip 5KB),节省 46KB。本工具页单页加载约 156KB,远低于 200KB 红线。
  2. XSS 防护更可控:成熟库功能丰富但攻击面也大,需配合 DOMPurify 净化 HTML。 本工具默认转义所有原始 HTML<script><iframe> 等), 从根本上杜绝 XSS,无需引入额外净化库。
  3. 维护可控:自实现解析器逻辑透明,遇到 bug 可即时修复,不依赖第三方更新节奏。 覆盖 GFM 子集已满足 95%+ 写作场景,复杂语法可按需扩展。
如何防止 XSS 攻击?我可以输入 <script>alert(1)</script> 吗?

可以输入但不会执行。本工具的解析器在渲染前会先转义所有 HTML 特殊字符&&amp;<&lt;>&gt;"&quot;'&#39;。 因此 <script>alert(1)</script> 会被原样显示为文本,不会被浏览器解析为脚本。

此外,URL 协议白名单会拦截 javascript:data: 等危险协议。 例如 [点我](javascript:alert(1)) 的链接 URL 会被清空,仅显示「点我」文本。 允许的协议:http、https、mailto、ftp、相对路径(/path)、锚点(#anchor)。

行内代码与代码块内容仅转义,不解析任何 Markdown 语法,确保代码示例原样显示。

双向同步滚动是怎么实现的?为什么有时会偏差?

同步滚动原理:监听编辑器与预览区的 scroll 事件,按 scrollTop / (scrollHeight - clientHeight) 计算滚动比例,再将比例乘以另一侧的最大滚动距离同步过去。为避免互相触发死循环,用 isSyncing 标志位 在同步期间屏蔽对方事件,并通过 requestAnimationFrame 在下一帧重置标志位。

偏差原因:编辑器与预览的内容长度比例不均匀。例如 Markdown 中一行表格语法 渲染为 HTML 可能是 5 行高的表格,导致滚动比例换算后预览区跳跃。这是所有 Markdown 编辑器的通病, GitHub / VS Code 也存在类似偏差。如需精确对照,可关闭同步滚动开关,手动滚动。

草稿会保存到哪里?清空浏览器会丢失吗?

草稿保存在浏览器的 localStorage,键名为 toolbox-markdown-draft。 每次输入变化后延迟 500ms 写入(去抖避免频繁 IO),刷新页面、关闭标签页后再次打开本工具会自动恢复草稿。

丢失场景:① 浏览器隐私模式(无痕窗口)localStorage 不持久; ② 手动清除浏览器数据时勾选「Cookie 与网站数据」会一并清除;③ 浏览器存储配额超限(通常 5-10MB, 约可存 200 万字符的 Markdown);④ 点击本工具的「清空」按钮会主动移除草稿。

重要文档请及时下载 HTML 备份,不要依赖 localStorage 长期保存。

导出的 HTML 文件包含什么?可以直接部署吗?

点击「下载 HTML」会导出一个独立的 .html 文件,包含:

  • 完整的渲染后 HTML 内容(段落、标题、代码块、表格等)
  • 内联的基础样式(字体、代码块背景、表格边框、引用样式等)
  • UTF-8 字符编码声明与移动端 viewport 适配

可以直接双击在浏览器打开预览,也可以上传到任意静态托管平台(Vercel / Cloudflare Pages / GitHub Pages) 作为独立页面部署。如需自定义样式,可在文件头部的 <style> 标签内修改。

注意:导出的 HTML 已经过 XSS 防护处理(原始 HTML 已转义),可安全分享。

支持嵌套列表吗?为什么我写的嵌套子项没有缩进?

当前版本不展开嵌套列表的层级缩进,所有列表项扁平渲染为同级 <li>。 例如:

- 父项
  - 子项
  - 子项

渲染为单个 <ul> 包含 3 个 <li>,子项不会缩进显示。 这是有意简化:完整嵌套需要解析缩进层级(2 空格 / 4 空格 / Tab),实现复杂度高且易出 bug。 临时方案:用引用块 > 或代码块表达层级,或导出 HTML 后手动调整。

未来版本如需支持嵌套,可基于缩进解析为嵌套 <ul>,欢迎在反馈渠道表达需求。

数据会上传到服务器吗?草稿会被追踪吗?

不会。本工具完全在浏览器内运行:Markdown 解析、HTML 渲染、草稿保存、文件下载均由 JavaScript 在你本地执行, 输入的内容不会发送到任何服务器。草稿保存在 localStorage 也仅限本机浏览器, 不会跨设备同步。这对于处理商业文档、内部资料、隐私笔记尤其重要。

但请注意:浏览器历史记录、屏幕截图、共享设备可能留下痕迹,如需彻底保密请在隐私模式中使用, 并在用完后清除 localStorage(点击「清空」按钮即可)。