v1.0.2 已发布

单文件
所见即所得
Markdown 编辑器

一行 <script> 引入即可使用。编辑时直接看到排版效果,代码高亮、表格、任务列表一应俱全。数据源可插拔,本地存储、REST API、内存任你选。

体积 单文件 · 约 50 KB
依赖 零外部依赖
许可 MIT 协议
index.html
<!-- 一行引入 -->
<script src="md-editor.js"></script>
<div id="editor"></div>
 
<script>
  const editor = MDEditor.create('#editor');
</script>
01 — 特性

为现代 Web 而生

该有的都有,不该有的都没有。零构建、零打包、零配置。

真正的所见即所得

编辑时直接看到最终排版。输入 # 空格变标题,**粗体** 立即渲染,无需切换源码和预览。

代码高亮

内置轻量高亮器,覆盖 JavaScript、TypeScript、Python、Go、Rust 等 14 种常见语言。也可注入 highlight.js 替换。

可插拔数据源

默认存 localStorage。通过 StorageAdapter 接口,20 行代码即可对接你自己的后端或云端存储。

常用 Markdown 语法

标题、列表、任务列表、引用、表格、代码块、分割线、图片、链接。所有语法块级与行内双向可逆。

暂不支持嵌套列表

UMD 打包

兼容 <script> 直接引入、CommonJS require、AMD 三种加载方式。

零依赖

没有 npm 包,没有构建工具,没有 CDN 请求。图标、样式、高亮器全部内联。

完整 API

getMarkdown()、setMarkdown()、save()、load()、destroy() 等 15 个方法,作为组件嵌入现有应用轻而易举。

乐观锁防冲突

更新文档时校验版本号,检测到并发修改会抛出 VERSION_CONFLICT 错误,交由宿主决定如何合并。

02 — 接入

四种接入方式

从最简单的一行代码,到完整的后端对接,都只要几分钟。

<!-- 1. 引入编辑器 -->
<script src="md-editor.js"></script>

<!-- 2. 放一个容器 -->
<div id="editor" style="height:600px"></div>

<!-- 3. 初始化 -->
<script>
  const editor = MDEditor.create('#editor');
</script>
const editor = MDEditor.create('#editor', {
  // 使用内置的 REST 适配器
  storage: MDEditor.adapters.REST({
    apiBase: '/api',
    token: localStorage.getItem('token'),
  }),

  // 加载已有文档(null 则新建)
  docId: 12345,

  // 生命周期回调
  onSave: (doc) => console.log('已保存', doc),
  onError: (err) => {
    if (err.code === 'VERSION_CONFLICT') {
      alert('文档已被他人修改');
    }
  },
});
// 20 行对接任何系统
const MyAdapter = {
  name: 'my-api',

  async list() {
    const res = await fetch('/docs');
    return (await res.json()).map(d => ({
      id: d.doc_id,
      title: d.name,
      updatedAt: d.ts * 1000,
      version: d.rev,
    }));
  },

  async get(id) { /* ... */ },
  async create(input) { /* ... */ },
  async update(id, input, version) { /* ... */ },
  async remove(id) { /* ... */ },
};

MDEditor.create('#editor', { storage: MyAdapter });
// 换成 highlight.js(或其他高亮引擎)
const editor = MDEditor.create('#editor', {
  highlighter: {
    highlight: (code, lang) => {
      if (window.hljs && hljs.getLanguage(lang)) {
        return hljs.highlight(code, {
          language: lang,
        }).value;
      }
      return code.replace(/[&<>]/g, c =>
        ({ '&': '&amp;', '<': '&lt;', '>': '&gt;' }[c]));
    },
  },
});
03 — API

实例方法

所有方法都返回 Promise 或数据本身,链式调用无负担。

方法返回说明
getMarkdown()string获取当前 Markdown 源码
setMarkdown(md)void设置编辑器内容
getTitle()string取文档标题(首个 H1 或 Untitled)
getDocId()string | null获取当前文档在数据源中的 ID
getVersion()number获取当前版本号(用于乐观锁)
isDirty()boolean是否有未保存的变更
save()Promise手动触发保存
newDoc()api重置为空文档(准备新建)
load(id)Promise从数据源加载指定文档
list()Promise列出所有文档(不含正文)
remove(id)Promise删除指定文档
setTheme(t)void切换主题('light' / 'dark')
setLang(lang)void切换界面语言('zh' / 'en')
focus()void聚焦编辑器
destroy()void销毁实例,清理事件监听

开始你的编辑器之旅

一行代码,即刻拥有一个专业级的 Markdown 编辑体验。