本仓库是 SimpleMDE,由 Sparksuite 制作 的一个分支。 更多信息请查看 专门的章节。
这是一个用于编写美观易懂的 Markdown 的即插即用的 JavaScript 文本区域替代品。 EasyMDE 允许经验较少的 Markdown 用户使用熟悉的工具栏按钮和快捷键。
此外,在编辑时会实时渲染语法,清晰地显示预期结果。标题更大,强调的词语变为斜体,链接带有下划线等。
EasyMDE 还具有内置的自动保存和拼写检查功能。 编辑器完全可定制,从主题到工具栏按钮和 JavaScript 钩子都可以自定义。
通过 npm:
npm install easymde
通过 UNPKG CDN:
<link rel="stylesheet" href="https://unpkg.com/easymde/dist/easymde.min.css"> <script src="https://unpkg.com/easymde/dist/easymde.min.js"></script>
或 jsDelivr:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/easymde/dist/easymde.min.css"> <script src="https://cdn.jsdelivr.net/npm/easymde/dist/easymde.min.js"></script>
安装和/或导入模块后,你可以将 EasyMDE 加载到网页上的第一个 textarea 元素:
<textarea></textarea> <script> const easyMDE = new EasyMDE(); </script>
或者你可以通过 JavaScript 选择特定的 textarea:
<textarea id="my-text-area"></textarea> <script> const easyMDE = new EasyMDE({element: document.getElementById('my-text-area')}); </script>
使用 easyMDE.value() 获取编辑器的内容:
<script> easyMDE.value(); </script>
使用 easyMDE.value(val) 设置编辑器的内容:
<script> easyMDE.value('New input for **EasyMDE**'); </script>
true,则强制下载Font Awesome(用于图标)。如果设置为 false,则阻止下载。默认为 undefined,会智能检查Font Awesome是否已经包含,然后相应地下载。true,则自动聚焦编辑器。默认为 false。true,则自动保存文本。默认为 false。10000(10秒)。autosave.delay 或 10000(10秒)。locale: en-US, format: hour:minute。{ delay: 300 },它将每300毫秒检查一次编辑器是否可见,如果是,则调用CodeMirror的 refresh()。** 或 __。默认为 **。``` 或 ~~~。默认为 ```。* 或 _。默认为 *。*、- 或 +。默认为 *。textarea 元素的DOM元素。默认为页面上的第一个 textarea 元素。true,强制在EasyMDE中做的文本更改立即存储在原始文本区域中。默认为 false。false,则使用空格而不是制表符进行缩进。默认为 true。false,图片预览仅会出现在单独行上的 图片。 括号之间的解析字符串作为参数,并返回一个字符串,作为预览中 <img> 标签的 src 属性。允许在前端动态预览图片,无需上传到服务器,允许将图片复制粘贴到编辑器中并进行预览。["[", "](http://)"]。
true,在编辑器中启用行号。false,禁用换行。默认为 true。"500px"。默认为 "300px"。minHeight 选项将被忽略。应该是一个包含有效CSS值的字符串,如 "500px"。默认为 undefined。true,否则为 false。true,将在 # 后没有空格的情况下渲染标题。默认为 false。false,将不处理GFM删除线语法。默认为 true。true,让下划线作为分隔单词的分隔符。默认为 false。false,将替换默认Markdown模式返回的CSS类。否则,自定义模式返回的类将与默认模式返回的类组合。默认为 true。"editor-preview"。true,会出现一个JS警告窗口,要求输入链接或图片URL。默认为 false。URL of the image:。URL for the link:。true,启用图片上传功能,可以通过拖放、复制粘贴和点击上传图片图标打开的浏览文件窗口触发。默认为 false。1024 * 1024 * 2(2 MB)。image/png, image/jpeg。imageMaxSize、imageAccept、imageUploadEndpoint 和 imageCSRFToken 选项失效。
onSuccess 和 onError 回调函数作为参数。onSuccess(imageUrl: string) 和 onError(errorMessage: string){"data": {"filePath": "<filePath>"}},其中 filePath 是图片的路径(如果 imagePathAbsolute 设置为true则为绝对路径,否则为相对路径);{"error": "<errorCode>"},其中 errorCode 可以是 noFileGiven(HTTP 400 Bad Request)、typeNotAllowed(HTTP 415 Unsupported Media Type)、fileTooLarge(HTTP 413 Payload Too Large)或 importError(参见下面的 errorMessages)。如果 errorCode 不是 errorMessages 之一,它将原样提示给用户。这允许服务器端错误消息。
无默认值。true,将把 imageUploadFunction 中的 imageUrl 和 imageUploadEndpoint 返回的 filePath 视为绝对路径,而不是相对路径,即不会在前面加上 window.location.origin。imageCSRFToken 有值时应用,默认为 csrfmiddlewaretoken。true,通过头部传递CSRF令牌。默认为 false,通过请求体传递CSRF。#image_name#、#image_size# 和 #image_max_size# 将被它们各自的值替换,可用于自定义或国际化:
uploadImage 设置为 true,初始显示的状态消息。默认为 Attach files by drag and dropping or pasting from clipboard.。Drop image to upload it.。Uploading images #images_names#。Uploading #file_name#: #progress#%。Uploaded #image_name#。 B, KB, MB(例如:218 KB)。如果你喜欢不带空格,可以使用 B,KB,MB(218KB)。errorCallback 选项显示给用户的错误,其中 #image_name#、#image_size# 和 #image_max_size# 将被它们各自的值替换,可用于自定义或国际化:
You must select a file.。imageAccept列表不匹配,或服务器返回此错误代码。默认为"不允许此图片类型"。imageMaxSize,或服务器返回此错误代码。默认为"图片#image_name#太大(#image_size#)。\n最大文件大小为#image_max_size#"。(errorMessage) => alert(errorMessage)。true,将使用highlight.js进行高亮。默认为false。要使用此功能,您必须在页面中包含highlight.js或通过hljs选项传入。例如,包含脚本和CSS文件如下:<br><script src="https://cdn.jsdelivr.net/highlight.js/latest/highlight.min.js"></script><br><link rel="stylesheet" href="https://cdn.jsdelivr.net/highlight.js/latest/styles/github.min.css">window.hljs),可以在此提供一个实例。默认为undefined。renderingConfig选项将优先生效。false,禁用解析GitHub风格Markdown(GFM)单行换行。默认为true。false,禁用拼写检查器。默认为true。可选择传入符合CodeMirrorSpellChecker的函数。textarea或contenteditable。桌面默认为textarea,移动设备默认为contenteditable。contenteditable选项对启用原生拼写检查是必要的。false,禁用原生拼写检查器。默认为true。false,允许并排编辑而不进入全屏模式。默认为true。false,隐藏状态栏。默认为内置状态栏项目数组。
false,从选中行移除CodeMirror-selectedtext类。默认为true。false,禁用并排模式下的滚动同步。默认为true。2。easymde。false,隐藏工具栏。默认为图标数组。false,禁用工具栏按钮提示。默认为true。"mde"时,加粗按钮的类变为"mde-bold"。rtl或ltr。更改文本方向以支持从右到左的语言。默认为ltr。大多数选项展示了非默认行为:
const editor = new EasyMDE({ autofocus: true, autosave: { enabled: true, uniqueId: "MyUniqueID", delay: 1000, submit_delay: 5000, timeFormat: { locale: 'en-US', format: { year: 'numeric', month: 'long', day: '2-digit', hour: '2-digit', minute: '2-digit', }, }, text: "自动保存: " }, blockStyles: { bold: "__", italic: "_", }, unorderedListStyle: "-", element: document.getElementById("MyID"), forceSync: true, hideIcons: ["guide", "heading"], indentWithTabs: false, initialValue: "你好,世界!", insertTexts: { horizontalRule: ["", "\n\n-----\n\n"], image: [""], link: ["[", "](https://)"], table: ["", "\n\n| 第1列 | 第2列 | 第3列 |\n| -------- | -------- | -------- |\n| 文本 | 文本 | 文本 |\n\n"], }, lineWrapping: false, minHeight: "500px", parsingConfig: { allowAtxHeaderWithoutSpace: true, strikethrough: false, underscoresBreakWords: true, }, placeholder: "在此输入...", previewClass: "my-custom-styling", previewClass: ["my-custom-styling", "more-custom-styling"], previewRender: (plainText) => customMarkdownParser(plainText), // 返回自定义解析器的HTML previewRender: (plainText, preview) => { // 异步方法 setTimeout(() => { preview.innerHTML = customMarkdownParser(plainText); }, 250); // 如果返回null,预览的innerHTML将不会被覆盖。 // 如果您通过vdom diffing控制预览节点的内容,这很有用。 // return null; return "加载中..."; }, promptURLs: true, promptTexts: { image: "自定义URL提示:", link: "自定义URL提示:", }, renderingConfig: { singleLineBreaks: false, codeSyntaxHighlighting: true, sanitizerFunction: (renderedHTML) => { // 使用DOMPurify并只允许<b>标签 return DOMPurify.sanitize(renderedHTML, {ALLOWED_TAGS: ['b']}) }, }, shortcuts: { drawTable: "Cmd-Alt-T" }, showIcons: ["code", "table"], spellChecker: false, status: false, status: ["autosave", "lines", "words", "cursor"], // 可选用法 status: ["autosave", "lines", "words", "cursor", { className: "keystrokes", defaultValue: (el) => { el.setAttribute('data-keystrokes', 0); }, onUpdate: (el) => { const keystrokes = Number(el.getAttribute('data-keystrokes')) + 1; el.innerHTML = `${keystrokes} 次按键`; el.setAttribute('data-keystrokes', keystrokes); }, }], // 另一种可选用法 ,带有统计按键次数的自定义状态栏项 styleSelectedText: false, sideBySideFullscreen: false, syncSideBySidePreviewScroll: false, tabSize: 4, toolbar: false, toolbarTips: false, toolbarButtonClassPrefix: "mde", });
以下是内置的工具栏图标(默认只启用了其中的一部分),你可以随意重新组织它们。"名称"是在JavaScript中引用的图标名称。"动作"可以是函数或要打开的URL。"类"是赋予图标的类。"工具提示"是通过title=""属性显示的小提示。请注意,快捷键提示会自动添加,并反映指定动作的键绑定(例如,当action设置为bold且tooltip设置为粗体时,用户最终看到的文本将是"粗体 (Ctrl-B)")。
此外,你可以通过在工具栏数组中添加"|"来在任意图标之间添加分隔符。
| 名称 | 动作 | 工具提示<br>类 |
|---|---|---|
| bold | toggleBold | 粗体<br>fa fa-bold |
| italic | toggleItalic | 斜体<br>fa fa-italic |
| strikethrough | toggleStrikethrough | 删除线<br>fa fa-strikethrough |
| heading | toggleHeadingSmaller | 标题<br>fa fa-header |
| heading-smaller | toggleHeadingSmaller | 较小标题<br>fa fa-header |
| heading-bigger | toggleHeadingBigger | 较大标题<br>fa fa-lg fa-header |
| heading-1 | toggleHeading1 | 大标题<br>fa fa-header header-1 |
| heading-2 | toggleHeading2 | 中标题<br>fa fa-header header-2 |
| heading-3 | toggleHeading3 | 小标题<br>fa fa-header header-3 |
| code | toggleCodeBlock | 代码<br>fa fa-code |
| quote | toggleBlockquote | 引用<br>fa fa-quote-left |
| unordered-list | toggleUnorderedList | 无序列表<br>fa fa-list-ul |
| ordered-list | toggleOrderedList | 有序列表<br>fa fa-list-ol |
| clean-block | cleanBlock | 清除格式<br>fa fa-eraser |
| link | drawLink | 创建链接<br>fa fa-link |
| image | drawImage | 插入图片<br>fa fa-picture-o |
| upload-image | drawUploadedImage | 打开文件浏览窗口<br>fa fa-image |
| table | drawTable | 插入表格<br>fa fa-table |
| horizontal-rule | drawHorizontalRule | 插入水平线<br>fa fa-minus |
| preview | togglePreview | 切换预览<br>fa fa-eye no-disable |
| side-by-side | toggleSideBySide | 切换并排显示<br>fa fa-columns no-disable no-mobile |
| fullscreen | toggleFullScreen | 切换全屏<br>fa fa-arrows-alt no-disable no-mobile |
| guide | 此链接 | Markdown指南<br>fa fa-question-circle |
| undo | undo | 撤销<br>fa fa-undo |
| redo | redo | 重做<br>fa fa-redo |
使用toolbar选项自定义工具栏。
仅调整现有按钮的顺序:
const easyMDE = new EasyMDE({ toolbar: ["bold", "italic", "heading", "|", "quote"] });
所有信息和/或添加你自己的图标或文本
const easyMDE = new EasyMDE({ toolbar: [ { name: "bold", action: EasyMDE.toggleBold, className: "fa fa-bold", title: "粗体", }, "italic", // 预制按钮的快捷方式 { name: "custom", action: (editor) => { // 添加你自己的代码 }, className: "fa fa-star", text: "已加星标", title: "自定义按钮", attributes: { // 用于自定义属性 id: "custom-id", "data-value": "custom value" // HTML5 data-* 属性需要用引号("")括起来,因为其名称中包含连字符(-)。 } }, "|" // 分隔符 // [, ...] ] });
将一些按钮放在下拉菜单中
const easyMDE = new EasyMDE({ toolbar: [{ name: "heading", action: EasyMDE.toggleHeadingSmaller, className: "fa fa-header", title: "标题", }, "|", { name: "others", className: "fa fa-blind", title: "其他按钮", children: [ { name: "image", action: EasyMDE.drawImage, className: "fa fa-picture-o", title: "图片", }, { name: "quote", action: EasyMDE.toggleBlockquote, className: "fa fa-percent", title: "引用", }, { name: "link", action: EasyMDE.drawLink, className: "fa fa-link", title: "链接", } ] }, // [, ...] ] });
EasyMDE自带一系列预定义的键盘快捷键,但可以通过配置选项进行更改。以下是默认快捷键列表:
| 快捷键 (Windows / Linux) | 快捷键 (macOS) | 操作 |
|---|---|---|
| <kbd>Ctrl</kbd>-<kbd>'</kbd> | <kbd>Cmd</kbd>-<kbd>'</kbd> | "切换引用块" |
| <kbd>Ctrl</kbd>-<kbd>B</kbd> | <kbd>Cmd</kbd>-<kbd>B</kbd> | "切换粗体" |
| <kbd>Ctrl</kbd>-<kbd>E</kbd> | <kbd>Cmd</kbd>-<kbd>E</kbd> | "清除块" |
| <kbd>Ctrl</kbd>-<kbd>H</kbd> | <kbd>Cmd</kbd>-<kbd>H</kbd> | "减小标题级别" |
| <kbd>Ctrl</kbd>-<kbd>I</kbd> | <kbd>Cmd</kbd>-<kbd>I</kbd> | "切换斜体" |
| <kbd>Ctrl</kbd>-<kbd>K</kbd> | <kbd>Cmd</kbd>-<kbd>K</kbd> | "插入链接" |
| <kbd>Ctrl</kbd>-<kbd>L</kbd> | <kbd>Cmd</kbd>-<kbd>L</kbd> | "切换无序列表" |
| <kbd>Ctrl</kbd>-<kbd>P</kbd> | <kbd>Cmd</kbd>-<kbd>P</kbd> | "切换预览" |
| <kbd>Ctrl</kbd>-<kbd>Alt</kbd>-<kbd>C</kbd> | <kbd>Cmd</kbd>-<kbd>Alt</kbd>-<kbd>C</kbd> | "切换代码块" |
| <kbd>Ctrl</kbd>-<kbd>Alt</kbd>-<kbd>I</kbd> | <kbd>Cmd</kbd>-<kbd>Alt</kbd>-<kbd>I</kbd> | "插入图片" |
| <kbd>Ctrl</kbd>-<kbd>Alt</kbd>-<kbd>L</kbd> | <kbd>Cmd</kbd>-<kbd>Alt</kbd>-<kbd>L</kbd> | "切换有序列表" |
| <kbd>Shift</kbd>-<kbd>Ctrl</kbd>-<kbd>H</kbd> | <kbd>Shift</kbd>-<kbd>Cmd</kbd>-<kbd>H</kbd> | "增大标题级别" |
| <kbd>F9</kbd> | <kbd>F9</kbd> | "切换并排视图" |
| <kbd>F11</kbd> | <kbd>F11</kbd> | "切换全屏" |
| <kbd>Ctrl</kbd>-<kbd>Alt</kbd>-<kbd>1</kbd> | <kbd>Cmd</kbd>-<kbd>Alt</kbd>-<kbd>1</kbd> | "切换一级标题" |
| <kbd>Ctrl</kbd>-<kbd>Alt</kbd>-<kbd>2</kbd> | <kbd>Cmd</kbd>-<kbd>Alt</kbd>-<kbd>2</kbd> | "切换二级标题" |
| <kbd>Ctrl</kbd>-<kbd>Alt</kbd>-<kbd>3</kbd> | <kbd>Cmd</kbd>-<kbd>Alt</kbd>-<kbd>3</kbd> | "切换三级标题" |
| <kbd>Ctrl</kbd>-<kbd>Alt</kbd>-<kbd>4</kbd> | <kbd>Cmd</kbd>-<kbd>Alt</kbd>-<kbd>4</kbd> | "切换四级标题" |
| <kbd>Ctrl</kbd>-<kbd>Alt</kbd>-<kbd>5</kbd> | <kbd>Cmd</kbd>-<kbd>Alt</kbd>-<kbd>5</kbd> | "切换五级标题" |
| <kbd>Ctrl</kbd>-<kbd>Alt</kbd>-<kbd>6</kbd> | <kbd>Cmd</kbd>-<kbd>Alt</kbd>-<kbd>6</kbd> | "切换六级标题" |
以下是如何更改一些快捷键,同时保留其他快捷键不变的方法:
const editor = new EasyMDE({ shortcuts: { "toggleOrderedList": "Ctrl-Alt-K", // 修改toggleOrderedList的快捷键 "toggleCodeBlock": null, // 解绑Ctrl-Alt-C "drawTable": "Cmd-Alt-T", // 将Cmd-Alt-T绑定到drawTable操作,该操作默认没有快捷键 } });
快捷键会自动在不同平台之间转换。如果你将快捷键定义为"Cmd-B",在PC上会自动变为"Ctrl-B"。相反,定义为"Ctrl-B"的快捷键在Mac用户那里会变成"Cmd-B"。
可以绑定的操作列表与工具栏按钮可用的内置操作列表相同。
你可以捕捉以下事件列表:https://codemirror.net/doc/manual.html#events
const easyMDE = new EasyMDE(); easyMDE.codemirror.on("change", () => { console.log(easyMDE.value()); });
你可以通过调用toTextArea方法恢复到初始的文本区域。注意,这会清除与之关联的自动保存(如果启用的话)。文本区域将保留被销毁的EasyMDE实例中的任何文本。
const easyMDE = new EasyMDE(); // ... easyMDE.toTextArea(); easyMDE = null;
如果你需要移除注册的事件监听器(当不再需要编辑器时),调用easyMDE.cleanup()。
以下自解释的方法在使用EasyMDE开发时可能会有用。
const easyMDE = new EasyMDE(); easyMDE.isPreviewActive(); // 返回布尔值 easyMDE.isSideBySideActive(); // 返回布尔值 easyMDE.isFullscreenActive(); // 返回布尔值 easyMDE.clearAutosavedValue(); // 无返回值
EasyMDE是SimpleMDE的延续。
SimpleMDE最初是对lepture的Editor项目的改进,但现在已经有了自己的特色。它与CodeMirror捆绑在一起,并依赖于Font Awesome。
CodeMirror是项目的核心,它在编写过程中解析大部分Markdown语法。这允许我们为正在编写的Markdown添加样式。此外,工具栏和状态栏分别被添加到顶部和底部。预览由Marked使用GitHub Flavored Markdown (GFM)渲染。
我最初创建这个分支是为了在SimpleMDE中实现FontAwesome 5的兼容性。完成后,我提交了一个拉取请求,但还没有被接受。这个情况,加上项目自2017年5月以来一直处于不活跃状态,促使我做出更多改变并尝试为项目注入新的生命力。
变更包括:
https://我的目标是继续开发这个项目,改进它并保持其活跃性。
你可能想要编辑这个库以适应你的需求。这可以通过以下几个快速步骤完成:
gulp命令,这将生成文件:dist/easymde.min.css和dist/easymde.min.js;想要为EasyMDE做出贡献吗?谢谢你!我们为你准备了一份贡献指南!
本项目基于MIT许可证发布。


AI赋能电商视觉革命,一站式智能商拍平台
潮际好麦深耕服装行业,是国内AI试衣效果最好的软件。使用先进AIGC能力为电商卖家批量提供优质的、低成本的商拍图。合作 品牌有Shein、Lazada、安踏、百丽等65个国内外头部品牌,以及国内10万+淘宝、天猫、京东等主流平台的品牌商家,为卖家节省将近85%的出图成本,提升约3倍出图效率,让品牌能够快速上架。


企业专属的AI法律顾问
iTerms是法大大集团旗下法律子品牌,基于最先进的大语言模型(LLM)、专业的法律知识库和强大的智能体架构,帮助企业扫清合规障碍,筑牢风控防线,成为您企业专属的AI法律顾问。


稳定高效的流量提升解决方案,助力品牌曝光
稳定高效的流量提升解决方案,助力品牌曝光


最新版Sora2模型免费使用,一键生成无水印视频
最新版Sora2模型免费使用,一键生成无水印视频


实时语音翻译/同声传译工具
Transly是一个多场景的AI大语言模型驱动的同声传译、专业翻译助手,它拥有超精准的音频识别翻译能力,几乎零延迟的使用体验和支持多国语言可以让你带它走遍全球,无论你是留学生、商务人士、韩剧美剧爱好者,还是出国游玩、多国会议、跨国追星等等,都可以满足你所有需要同传的场景需求,线上线下通用,扫除语言障碍,让全世界的语言交流不再有国界。


选题、配图、成文,一站式创作,让内容运营更高效
讯飞绘文,一个AI集成平台,支持写作、选题、配图、排版和发布。高效生成适用于各类媒体的定制内容,加速品牌传播,提升内容营销效果。


AI辅助编程,代码自动修复
Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。


最强AI数据分析助手
小浣熊家族Raccoon,您的AI智能助手,致力于通过先进的人工智能技术,为用户提供高效、便捷的智能服务。无论是日常咨询还是专业问题解答,小浣熊都能以快速、准确的响应满足您的需求,让您的生活更加智能便捷。


像人一样思考的AI智能体
imini 是一款超级AI智能体,能根据人类指令,自主思考、自主完成、并且交付结果的AI智能体。


AI数字人视频创作平台
Keevx 一款开箱即用的AI数字人视频创作平台,广泛适用于电商广告、企业培训与社媒宣传,让全球企业与个人创作者无需拍摄剪辑,就能快速生成多语言、高质量的专业视频。
最新AI工具、AI资讯
独家AI资源、AI项目落地

微信扫一扫关注公众号