This translation is older than the English page and may be missing recent changes.
Read the English version一個 Markdown 編輯器,可以增強您的文字區域而不是替換它,因此表單提交、驗證和必填欄位可以繼續工作。所見即所得和純 Markdown 模式、即時預覽、尋找和替換、RTL 支援、深色模式。可與 Django、Laravel、Rails、Node.js、PHP 和任何堆疊獨立工作。
**不需要 Frutjam 和 Tailwind。 ** 樣式是捆綁的,因此編輯器可以放入任何項目中。
安裝
NPM(捆綁器:Vite、webpack、Rollup 等)
npm install markdown-text-editor |
1 2 | import MarkdownEditor from 'markdown-text-editor'; new MarkdownEditor('#markdown-editor'); |
TypeScript 定義隨軟體包一起提供,因此選項、工具列條目和變數形狀都會被檢查並自動完成,無需額外安裝。
這些類型也是可匯入的,只要您的選項不是在呼叫網站內聯編寫的,這一點就很重要。 TypeScript 僅檢查直接傳遞的物件文字上的未知鍵,因此儲存在自己的變數中的配置會默默忽略拼字錯誤的鍵。對其進行註釋會將檢查放回原處。
1 2 3 4 5 6 7 8 9 10 11 12 13 | import MarkdownEditor, { type MarkdownEditorOptions, type ToolbarEntry } from 'markdown-text-editor'; // Without the annotation this compiles, the editor renders with the default // toolbar, and nothing tells you why. const config: MarkdownEditorOptions = { placeholder: 'Write...', toolbr: ['bold', 'preview'], // Error: did you mean to write 'toolbar'? }; // Building a toolbar conditionally const toolbar: ToolbarEntry[] = ['bold', 'italic']; if (canUpload) toolbar.push({ image: { fileInput: { uploadUrl: '/api/upload' } } }); toolbar.push('preview'); |
這同樣適用於包裝組件,其中 MarkdownEditorOptions 是你轉發的而不是 any,所以無論誰使用你的包裝器都會進行檢查。
1 2 3 4 | interface EditorProps { value: string; options?: MarkdownEditorOptions; } |
CDN:ES模組
1 2 3 4 | <script type="module"> import MarkdownEditor from 'https://cdn.jsdelivr.net/npm/markdown-text-editor/+esm'; new MarkdownEditor('#markdown-editor'); </script> |
CDN:全域腳本標籤(IIFE)
無需導入:MarkdownEditor 可自動作為全域變數使用。
1 2 3 4 5 6 7 8 9 | <form action="/api/save" method="POST"> <textarea id="markdown-editor" name="content"># Hello World</textarea> <button type="submit">Save Content</button> </form> <script src="https://cdn.jsdelivr.net/npm/markdown-text-editor"></script> <script> new MarkdownEditor('#markdown-editor'); </script> |
Markdown 編輯器演示
快速入門
傳遞一個選項物件來自訂編輯器。所有選項都是可選的:省略任何選項即可使用預設值。
1 2 3 4 | const editor = new MarkdownEditor('#markdown-editor', { placeholder: 'Write your markdown...', toolbar: ['heading', 'bold', 'italic', 'strikethrough', 'ul', 'ol', 'checklist', 'blockquote', 'link', 'preview'], }); |
理念:“本土第一”
大多數編輯器都打破了標準的網路工作流程。 MarkdownEditor 擁抱它。因為它直接位於 <textarea>,您不需要學習處理資料的新方法。
- 無需資料綁定: 適用於
<form method="POST">開箱即用 - 標準訪問: 使用
document.getElementById('editor').value就像普通輸入一樣。 - 與後端無關: 可與任何後端(Python、Node.js、PHP 等)一起使用,就像普通表單欄位一樣
MarkdownEditor 與 EasyMDE / SimpleMDE
大多數 JavaScript Markdown 編輯器(EasyMDE、SimpleMDE、基於 CodeMirror 的編輯器)隱藏您的 <textarea> 並編輯副本,提交表單時寫回內容。這一直有效,直到其他東西需要該值: required 瀏覽器無法聚焦的欄位會完全阻止提交,並且 .value 或者 FormData 在提交之前讀取會傳回一個空字串,這會破壞 htmx、Turbo、自動儲存和未儲存變更防護。 **MarkdownEditor 是不同的。 ** 它對您已有的文字區域進行樣式設置,並將其保留為您輸入的字段,因此該值在任何時候都是正確的。
| 特徵 | Markdown編輯器 | EasyMDE / SimpleMDE |
|---|---|---|
| 保留本機文字區域 | ✅ | ❌ 隱藏,編輯為副本 |
與 required 領域 | ✅ | ❌ 瀏覽器阻止提交 |
.value 提交前更正 | ✅ | ❌ 表單提交之前為空 |
連載於 FormData, htmx, 渦輪增壓 | ✅ | ❌ 需要編輯器自己的API |
| 所見即所得混合模式 | ✅ | ❌ |
| 內建尋找和替換 | ✅ | ❌ |
| RTL 支持 | ✅ 內置 | 透過 CodeMirror 的 direction 選項 |
| 內嵌事件處理程序 (CSP) | ✅ 無 | 一些 |
| 深色模式/主題 | ✅ | 有限的 |
| 捆綁包大小,gzip 壓縮 | 53 KB | 107 KB(JS + CSS) |
框架整合
因為 MarkdownEditor 保留了原生 <textarea>,它與每個後端框架集成,無需任何額外程式碼。您的伺服器接收 Markdown 內容,就像從任何標準表單欄位接收一樣。對於 React 和 Vue,它需要幾行,在本節末尾介紹。
薑戈
添加一個 class 到您的文字區域小部件並初始化編輯器: request.POST['content'] 無需額外步驟即可工作。
1 2 3 4 5 6 7 8 | # forms.py class PostForm(forms.ModelForm): class Meta: model = Post fields = ['content'] widgets = { 'content': forms.Textarea(attrs={'class': 'markdown-editor'}), } |
1 2 | new MarkdownEditor('.markdown-editor'); // request.POST['content'] contains the markdown on submit |
拉維爾
使用 f.text_area 有一個類別: $request->input('content') 直接接收markdown。
1 2 | <textarea name="content" class="markdown-editor">{{ old('content') }}</textarea> <script>new MarkdownEditor('.markdown-editor');</script> |
紅寶石 on Rails
與 form_with 開箱即用: params[:content] 包含降價。對於渦輪驅動器,請使用 turbo:load 而不是 DOMContentLoaded.
1 2 3 4 5 6 | document.addEventListener('turbo:load', () => { document.querySelectorAll('.markdown-editor:not([data-mde-init])').forEach(el => { el.setAttribute('data-mde-init', 'true'); new MarkdownEditor(el); }); }); |
Node.js / Express
req.body.content 接收表單提交時的降價:沒有同步步驟,沒有自訂提取。
1 2 3 | <textarea name="content" class="markdown-editor"></textarea> <script src="https://cdn.jsdelivr.net/npm/markdown-text-editor"></script> <script>new MarkdownEditor('.markdown-editor');</script> |
PHP
$_POST['content'] 與任何標準文字區域完全相同:將其放入,您現有的表單處理需要零更改。
1 2 3 4 5 6 | <form method="POST" action="save.php"> <textarea name="content" class="markdown-editor"></textarea> <button type="submit">Save</button> </form> <script src="https://cdn.jsdelivr.net/npm/markdown-text-editor"></script> <script>new MarkdownEditor('.markdown-editor');</script> |
反應
在效果中建立編輯器並在卸載時銷毀它。使用 defaultValue 而不是 value:編輯器直接寫入文字區域,因此受控綁定將覆蓋使用者鍵入的內容。
1 2 3 4 5 6 7 8 9 10 11 12 13 | import { useEffect, useRef } from 'react'; import MarkdownEditor from 'markdown-text-editor'; function MarkdownField({ name, defaultValue = '', onChange }) { const ref = useRef(null); useEffect(() => { const editor = new MarkdownEditor(ref.current, { onChange }); return () => editor.destroy(); }, []); return <textarea ref={ref} name={name} defaultValue={defaultValue} />; } |
返回 editor.destroy() from theeffect 還涵蓋了 StrictMode,它在開發過程中運行兩次效果,否則會在一個文字區域上留下兩個編輯器。空依賴數組是故意的:在建立編輯器時會讀取一次選項,因此重新運行效果會拆除它並在每次更改時重建它。
維埃
同樣的想法。設定一次初始值 onMounted 並且不綁定 :value,或透過發送回的每個擊鍵 v-model 會覆蓋文字區域。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <script setup> import { ref, onMounted, onBeforeUnmount } from 'vue'; import MarkdownEditor from 'markdown-text-editor'; const el = ref(null); const props = defineProps({ modelValue: { type: String, default: '' } }); const emit = defineEmits(['update:modelValue']); let editor = null; onMounted(() => { el.value.value = props.modelValue; editor = new MarkdownEditor(el.value, { onChange: value => emit('update:modelValue', value) }); }); onBeforeUnmount(() => editor?.destroy()); </script> <template><textarea ref="el"></textarea></template> |
用作 <MarkdownField v-model="content" />。在簡單的形式中,您可以跳過 v-model 與任何其他框架一樣,完全並在提交時從文字區域讀取值。
配置
您可以透過傳遞一個來完全自訂編輯器的行為和介面 options 目的。如果省略選項,則使用 預設 值。
建置編輯器時,選項將被讀取一次。之後更改它們沒有任何效果:調用 destroy() 並建立一個新的編輯器。
| 財產 | 類型 | 預設 | 目的 |
|---|---|---|---|
mode | string | 'plain' | 設定初始視圖。使用混合以獲得所見即所得的體驗,或使用普通的原始語法。 |
placeholder | string | 'Write...' | 編輯器為空時顯示的文字。 |
toolbar | array | [...] | 定義顯示哪些工具以及顯示順序。 |
footer | 假| 對象 | 全部可見 | 控制編輯器下方顯示的狀態列。設定為 false 完全隱藏它,或傳遞一個物件來切換單一統計資料。 |
theme | string | inherited | 明確設定編輯器主題(淺色、深色、雪莓、黑莓)。如果省略,編輯器繼承 data-theme 從最近的祖先元素或 <textarea> 本身。 |
minHeight | number | 200 | 當內容較短時,編輯器將縮小到的最小高度(以像素為單位)。配對 maxHeight 設定自動增長範圍。 |
maxHeight | number | 500 | 編輯器在非全螢幕模式下可以增長到的最大高度(以像素為單位)。一旦內容超過此高度,編輯器內就會出現捲軸。該編輯器還有一個拖曳手柄,因此使用者可以手動將其大小調整到超出此限制。 |
renderer | function | marked | 替換用於預覽的 Markdown 解析器。接收 markdown 字串並且必須傳回 HTML 字串。 |
sanitizer | function | DOMPurify | 取代 HTML 清理程式。接收渲染的 HTML,必須傳回安全的 HTML 來顯示。 |
onChange | function | undefined | 每次內容變更時都會觸發回調:鍵入、工具列操作、撤銷/重做和清單延續。接收目前的 markdown 字串作為其唯一的參數。 |
labels | object | undefined | 編輯器本身介面的翻譯,由英文字串鍵入。您遺漏的任何內容都將保留為英文。 |
🛠 工具列自訂
工具列是模組化的。您可以透過修改陣列來創建最低限度的體驗或功能齊全的電源套件。
可用工具
| 類別 | 工具鍵 |
|---|---|
| 版式 | heading, bold, italic, strikethrough, blockquote |
| 清單 | ul (bullet), ol (numbered), checklist |
| 程式碼 | code (排隊), codeblock (圍欄塊) |
| 刀片 | hr (水平規則), table (表格範本) |
| 媒體 | link, image |
| 編輯 | undo, redo, indent, outdent |
| 看法 | preview |
| 範本 | { variables: [...] }, 內聯配置 |
工具參考
| 工具 | 描述 |
|---|---|
heading | 開啟下拉式選單以選擇標題等級 H1–H6 |
bold | 啟用粗體文字格式。 |
italic | 啟用斜體文字格式。 |
strikethrough | 允許文字刪除線。 |
ol | (有序列表):將文字轉換為編號清單格式。 |
ul | (無序列表):將文字轉換為項目符號清單。 |
checklist | 在文字中新增複選框,使其非常適合任務、待辦事項清單或追蹤完成狀態。 |
blockquote | 反白顯示引用或強調的文字。 |
code | 將選定的文字包含在單一反引號中以實現內聯代碼。再次點選可刪除反引號。 |
codeblock | 將選定的文字包裝在三重反引號圍欄程式碼區塊中。再次點選可移除柵欄。 |
hr | 插入一個 --- 水平線位於其自己的行上的遊標位置。 |
table | 在遊標位置插入起始 2x3 Markdown 表格範本。 |
image | 讓您透過 Markdown 語法插入圖片。 |
link | 允許您向文字添加超連結。 |
undo | 撤銷最後的變更。 |
redo | 重新套用上次撤銷的變更。 |
indent | 增加縮排等級。 |
outdent | 降低壓痕等級。 |
preview | 切換全螢幕並排預覽。預覽窗格中的核取方塊可按一下並立即更新 Markdown 來源。按 Esc 鍵退出全螢幕。如果固定標題覆蓋全螢幕編輯器,請參閱 --mte-fullscreen-z-index. |
💡實施技巧:
- 重新排序:按鈕會依照您在陣列中列出的確切順序顯示
- 刪除:只需省略任何鍵(例如
image) 從陣列中完全為使用者停用該功能 - 本機後備:如果您不提供
placeholder在 JS 中,插件會自動使用placeholder來自 HTML 的屬性<textarea>
🧩 自訂工具
添加您自己的工具列按鈕,無需分叉。描述它並將其放入 toolbar 數組,在任何你想要的位置。
1 2 3 4 5 6 7 8 9 10 11 | new MarkdownEditor('#markdown-editor', { toolbar: ['bold', 'italic', { custom: { title: 'Callout', icon: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20">…</svg>', action(editor) { editor.insertText('> [!NOTE]\n> Something worth noting'); } } }, 'preview'] }); |
這 title 成為工具提示和按鈕的 CSS 類,因此這個樣式可設定為 .callout-btn,與內建工具完全相同。
幾個工具
添加任意數量。每個工具都是數組中自己的條目,因此您可以單獨放置它們,並且它們可以位於內建工具之間,而不是分組在一端。
1 2 3 4 5 6 7 | toolbar: [ 'bold', 'italic', { custom: { title: 'Callout', icon: svg1, action: insertCallout } }, 'ul', 'ol', { custom: { title: 'Signature', icon: svg2, action: insertSignature } }, 'preview' ] |
賦予每一個獨特的 title。共享同一個標題的兩個工具將共享一個 CSS 類,而沒有標題的工具會退回到 .custom-btn.
選項
| 財產 | 類型 | 目的 |
|---|---|---|
title | string | 必需的。工具提示文字和按鈕 CSS 類別的來源。可翻譯透過 labels. |
action | function | 必需的。收到 (editor, event)。单击事件被传递,以便打开对话框的工具可以将其传递给 MarkdownEditor.modal. |
icon | string | 按鈕面的內嵌 SVG。 |
shortcut | string | 鍵盤快速鍵,如 Ctrl+Shift+K。新增至工具提示,並優先於使用相同按鍵的內建工具提示。 |
一個工具沒有 action 會跳過並顯示控制台警告,而不是破壞工具列。它不渲染任何按鈕,而且它的 shortcut,如果它聲明了,也沒有註冊。
處理內容
使用 editor.insertText() 而不是自己寫入文字區域。它會取代選擇、恢復焦點、移動插入符、捲動、重新渲染預覽並觸發 onChange。撤銷操作仍然有效,因為編輯是透過正常路徑進行的。
1 2 3 4 5 6 7 8 | action(editor) { const textarea = editor.usertextarea; const selected = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd); const wrapped = `==${selected || 'highlight'}==`; // (text, where the caret lands, characters to leave outside the selection) editor.insertText(wrapped, wrapped.length, 0); } |
快速方式
1 2 3 4 5 6 | { custom: { title: 'Highlight', icon: '<svg>…</svg>', shortcut: 'Ctrl+Shift+H', action: (editor) => editor.insertText('====', 2, 2) }} |
工具提示變為「突出顯示 (Ctrl+Shift+H)」。工具快捷方式會在內建捷徑之前進行檢查,因此自訂工具可以故意接管編輯器本來可以處理的組合。
需要自己標記的工具
下拉清單或對話方塊無法以宣告方式描述,因此請編寫一個類別。延長 MarkdownEditor.Tool, 放 this.button 在建構函式中,並實現 applySyntax().
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | class EmbedTool extends MarkdownEditor.Tool { constructor(editor) { super(editor, 'Embed video'); // tooltip, and .embed-video-btn this.shortcut = 'Ctrl+Shift+E'; // optional this.button = this.createButton('<svg>…</svg>'); } applySyntax(event) { const dialog = MarkdownEditor.modal(event, 'fj:max-w-sm', ` <input type="url" class="embed-url fj:me-input fj:w-full"> <button type="button" class="embed-go fj:me-btn fj:me-btn-sm">Insert</button> `, 'Embed'); dialog.querySelector('.embed-go').addEventListener('click', () => { const url = dialog.querySelector('.embed-url').value.trim(); if (url) this.editor.insertText(`\n<iframe src="${url}"></iframe>\n`); dialog.close(); }); } destroy() { // Called by editor.destroy(). Release anything you registered here. } } new MarkdownEditor('#markdown-editor', { toolbar: ['bold', EmbedTool, 'preview'] }); |
透過配置 { tool: EmbedTool, config: {...} },它作為建構函數的第二個參數到達。環境 this.button 到 null 不渲染任何內容,這對於僅適用於某些配置的工具很有用。
需要注意的一件事: Tool的構造函數調用 createButton(),所以你的覆蓋需要的任何東西都必須來自 this.editor,不是來自您之後分配的字段 super().
對話框助手
MarkdownEditor.modal 是內建連結和圖像工具使用的對話框,因此您收集輸入的工具看起來就像編輯器的其餘部分,而不是發明自己的彈出視窗。它返回 <dialog> 元素,已打開,您可以查詢字段並用其關閉 dialog.close().
1 2 | // (event, size classes, body HTML, aria label) const dialog = MarkdownEditor.modal(event, 'fj:max-w-sm', '…', 'Embed'); |
透過 event 你的 applySyntax() 已收到。幫助器讀取它以查找單擊來自哪個編輯器,因此對話框將附加到該編輯器的包裝器內並選擇其主題。它會取代該編輯器中已開啟的所有對話框,並在關閉時將其自身從 DOM 中刪除,因此無需清理任何內容。
自己渲染 Markdown
如果您的工具嵌入了渲染內容(例如工具提示主體), editor.renderMarkdown() 產生與預覽完全相同的 HTML,尊重您的 renderer 和 sanitizer.
const html = editor.renderMarkdown('**bold** text'); |
您自己的文字區域的工具列
當對話方塊收集富文本時,為其提供真正的格式化工具,而不是重建它們。工具列綁定到您傳遞的文字區域,您的 labels 都是繼承的,沒有加入預覽按鈕。
1 2 3 | const body = dialog.querySelector('textarea'); const bar = editor.createToolbar(body, ['bold', 'italic', 'strikethrough']); dialog.querySelector('.body-toolbar').appendChild(bar); |
這不會管理工具列的生命週期。當對話方塊被刪除時,這些按鈕會隨著對話方塊一起清理,但是如果其中的工具註冊了頁面範圍內的任何內容、文件偵聽器或計時器,請在對話方塊關閉時自行釋放它們。
翻譯
自訂工具可以像內建工具一樣進行翻譯,由您賦予它們的標題鍵入。
labels: { 'Callout': 'Aviso', 'Embed video': 'Insertar video' } |
CSS 類別不受影響,所以 .callout-btn 停留 .callout-btn 每種語言。
📊 頁腳(狀態列)
頁腳位於編輯器下方,顯示遊標的行、列、文檔的字元數以及可選的字數,所有這些都是即時更新的。預設情況下它是可見的,並且每個統計資料都可以獨立切換。
| 鑰匙 | 類型 | 預設 | 描述 |
|---|---|---|---|
line | boolean | true | 顯示目前行號。 |
col | boolean | true | 顯示目前的列號。 |
chars | boolean | true | 顯示總字元數。 |
words | boolean | false | 顯示總字數。預設關閉:設定為 true 啟用。 |
使用範例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | // Default — line, col, and chars visible new MarkdownEditor('#editor'); // Disable the footer entirely new MarkdownEditor('#editor', { footer: false }); // Hide only character count new MarkdownEditor('#editor', { footer: { chars: false } }); // Hide line and column, keep character count new MarkdownEditor('#editor', { footer: { line: false, col: false } }); // Show only line number new MarkdownEditor('#editor', { footer: { col: false, chars: false } }); // Enable word count alongside the defaults new MarkdownEditor('#editor', { footer: { words: true } }); // Show word count only new MarkdownEditor('#editor', { footer: { line: false, col: false, chars: false, words: true } }); |
🔀 編輯模式
MarkdownEditor 提供兩種不同的方式來撰寫和格式化內容。您可以在傳統的以語法為中心的視圖或現代的視覺優先體驗之間切換。
plain(預設):一個乾淨、高效能的 Markdown 環境,其中語法(例如**bold**或者# heading) 可見。開發人員和 Markdown 純粹主義者的理想選擇hybrid:所見即所得的體驗,可在您鍵入時即時呈現格式(粗體、斜體、標題),同時仍保持底層 Markdown 結構。
1 2 3 4 5 6 7 8 9 10 11 12 | // Default initialization (Plain Mode) new MarkdownEditor('#markdown-editor'); // Explicit Plain Mode new MarkdownEditor('#markdown-editor', { mode: 'plain' }); // Hybrid (Visual) Mode new MarkdownEditor('#markdown-editor', { mode: 'hybrid' }); |
混合和普通模式預覽:
混合模式
當您鍵入時,視覺格式會即時呈現。
普通模式(預設)
專注於原始 Markdown 語法以提供輕量級體驗。
🌙 主題化
MarkdownEditor 自動從周圍頁面繼承其主題:無需配置。編輯讀到 data-theme 從初始化時最近的祖先開始,因此它與您網站的開箱即用主題保持同步。
主題如何解決(優先順序)
themeoption:在選項物件中傳遞的明確覆蓋data-theme於<textarea>:直接在元素上設置data-theme任何祖先:例如<html>,<body>,或包裝器<div>
可用主題
'light' (預設), 'dark', 'snowberry', 'darkberry'
選項1,繼承自 <html> 或任何祖先(零配置)
1 2 3 4 5 6 | <html data-theme="dark"> ... <textarea id="markdown-editor"></textarea> <script> new MarkdownEditor('#markdown-editor'); // picks up dark automatically </script> |
選項 2:設定 data-theme 直接在 <textarea>
1 2 3 4 | <textarea id="markdown-editor" data-theme="dark"></textarea> <script> new MarkdownEditor('#markdown-editor'); </script> |
選項 3:顯式 theme 選項(覆蓋所有內容)
1 2 3 | new MarkdownEditor('#markdown-editor', { theme: 'dark' }); |
🎨 透過 CSS 變數自訂主題
您可以透過覆寫其 CSS 變數來完全自訂編輯器的外觀 .markdown-editor-wrapper 元素或任何 [data-theme] 選擇器。所有顏色均使用 OKLCH 色彩空間 以獲得感知上統一的結果。
| 多變的 | 目的 | 淺色預設 | 深色預設 |
|---|---|---|---|
--color-base | 編輯背景 | oklch(100% 0 0) | oklch(10.9% 0 0) |
--color-on-base | 主要文字顏色 | oklch(22% 0 0) | oklch(98% 0 0) |
--color-primary | 主要重音(工具列活動,連結) | oklch(51.1% .262 277) | oklch(66.4% .184 286) |
--color-on-primary | 原色表面上的文字 | oklch(96.2% .018 272) | oklch(10% .01 270) |
--color-secondary | 次要口音 | oklch(59.1% .293 323) | oklch(65% .18 220) |
--color-accent | 反白顯示重音符號(內聯代碼,斜體) | oklch(54.1% .281 293) | oklch(75% .18 50) |
--color-neutral | 中性表面(邊界、分隔線) | oklch(15% 0 0) | oklch(85% 0 0) |
--color-error | 錯誤狀態顏色 | oklch(57.7% .245 27) | oklch(60% .22 30) |
--border-radius | 編輯器框架的圓角 | 0.25rem |
自訂主題範例
覆蓋任何變數 .markdown-editor-wrapper 編輯器初始化後,或定義自訂 [data-theme] 樣式表中的區塊:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | /* Override individual variables */ .markdown-editor-wrapper { --color-primary: oklch(60% 0.2 30); /* orange accent */ --border-radius: 0.5rem; } /* Or define a full custom theme */ [data-theme="brand"] .markdown-editor-wrapper, .markdown-editor-wrapper[data-theme="brand"] { --color-base: oklch(15% 0.01 250); --color-on-base: oklch(95% 0 0); --color-primary: oklch(65% 0.22 145); /* green */ --color-on-primary: oklch(10% 0 0); --color-accent: oklch(75% 0.18 60); --color-neutral: oklch(80% 0 0); --border-radius: 0.75rem; } |
new MarkdownEditor('#markdown-editor', { theme: 'brand' }); |
🌐 介面語言
編輯器自己的文字、工具提示、選單項目、模式欄位和按鈕預設為英文。透過一個 labels 物件翻譯它。鍵是英文字串,即 gettext 的工作方式,因此您只需列出要更改的內容,而缺少的任何內容都會恢復為英文。
1 2 3 4 5 6 7 8 9 10 11 12 13 | new MarkdownEditor('#markdown-editor', { labels: { 'Bold': 'Gras', 'Italic': 'Italique', 'Heading': 'Titre', 'Link': 'Lien', 'Image link': 'Lien de l\'image', 'URL': 'URL', 'Alt text': 'Texte alternatif', 'Apply': 'Appliquer', 'Uploading...': 'Téléversement...', }, }); |
這與從右到左的內容一起最重要。阿拉伯語、烏爾都語和波斯語本身佈局正確,但在從右到左的文本上仍然顯示“粗體”的工具列僅翻譯了一半。
🏷 變數
新增用於插入佔位符的工具列下拉清單。當編寫文件的人不是定義佔位符語法的開發人員時很有用,例如電子郵件、發票或合約範本:他們選擇一個可讀的名稱,並為其插入正確的語法。
1 2 3 4 5 6 7 8 9 | new MarkdownEditor('#markdown-editor', { toolbar: ['bold', 'italic', 'link', { variables: [ { label: 'Customer Name', value: '{{customer.name}}' }, { label: 'Invoice No', value: '{{invoice.number}}' } ]}, 'preview' ] }); |
該工具是內聯配置的 toolbar 數組,因此它在其他按鈕中的位置取決於您。該按鈕列出了標籤,單擊其中一個即可插入其標籤 value 在遊標處,替換任何選擇。如果清單為空,則不會呈現任何內容。
預覽中的範例值
給定一個條目 sample 在預覽中顯示該範例,而文字區域保留真實的佔位符。沒有其中之一的條目將以書面形式顯示,因此您可以將兩者混合使用。
1 2 3 4 5 6 7 | { variables: [ { label: 'Customer Name', value: '{{customer.name}}', sample: 'Hannes' }, { label: 'Invoice No', value: '{{invoice.number}}' } ]} // textarea : Hi {{customer.name}}, invoice {{invoice.number}} // preview : Hi Hannes, invoice {{invoice.number}} |
分組
給出一個條目 items 而不是 value 渲染一個有標題的部分。分組條目和平面條目可以混合在一個清單中。
1 2 3 4 5 6 7 8 9 10 | { variables: [ { label: 'Today', value: '{{today}}', sample: '10 September 2026' }, { label: 'Customer', items: [ { label: 'Name', value: '{{customer.name}}', sample: 'Hannes' }, { label: 'Email', value: '{{customer.email}}', sample: 'hannes@example.com' } ]}, { label: 'Invoice', items: [ { label: 'Number', value: '{{invoice.number}}' } ]} ]} |
要知道的事情
- **編輯器從不解析變數。 ** 它插入文本,然後您的應用程式通常在伺服器端替換實際值。
sample僅影響預覽顯示的內容。 - 標籤顯示為純文字,因此標籤中的標記永遠不會呈現。
- 格式錯誤的條目將被跳過而不是拋出,並且當未配置任何可用的內容時,根本不會呈現按鈕。
🖋 自訂渲染器
預覽呈現為 標記的 並用消毒 DOM純化。兩者都可以更換。當您的應用程式已經使用另一個程式庫呈現 Markdown 並且您希望預覽與生產完全匹配時,請使用此選項。
這兩個選項都是普通函數,它們接受一個字串並傳回一個字串,因此任何解析器和任何清理程式都可以工作。
1 2 3 4 5 6 7 8 9 | import MarkdownIt from 'markdown-it'; import taskLists from 'markdown-it-task-lists'; import MarkdownEditor from 'markdown-text-editor'; const md = new MarkdownIt({ linkify: true, breaks: true }).use(taskLists); new MarkdownEditor('#markdown-editor', { renderer: markdown => md.render(markdown) }); |
DOMPurify 仍然在輸出上運行,因此您無需配置任何內容即可保持 XSS 保護。
客製化消毒液
僅當預設刪除渲染器發出的內容時才需要。 DOMPurify 刪除 <iframe> 預設情況下,因此視訊嵌入需要明確允許。 DOMPurify 必須在您自己的程式碼中匯入,因為與編輯器捆綁的副本是內部的。
1 2 3 4 5 6 7 8 9 | import DOMPurify from 'dompurify'; new MarkdownEditor('#markdown-editor', { renderer: markdown => md.render(markdown), sanitizer: html => DOMPurify.sanitize(html, { ADD_TAGS: ['iframe'], ADD_ATTR: ['allow', 'allowfullscreen', 'frameborder'] }) }); |
使用腳本標籤而不是捆綁器,將 DOMPurify 與編輯器一起載入:
1 2 | <script src="https://cdn.jsdelivr.net/npm/dompurify"></script> <script src="https://cdn.jsdelivr.net/npm/markdown-text-editor"></script> |
要知道的事情
- **僅限預覽。 ** 混合模式的即時格式使用單獨的內部渲染器,且不受影響。
- **任務清單需要插件支援。 **可透過尋找找到可點選的複選框
input[type="checkbox"]在輸出中,所以 markdown-it 需要markdown-it-task-lists。如果編輯器偵測到任務清單語法且沒有複選框,則會記錄警告。 - 兩者必須同步並傳回一個字串。一個
async函數寫入[object Promise]進入預覽。 - **更换消毒剂就取代了您的保护。 ** 傳遞,例如
html => html完全禁用清理,並且僅對完全信任的內容是安全的。
🎨 設定內部元素的樣式
CSS 變數涵蓋了大多數主題,因為它們是繼承的,因此設定一個 .markdown-editor-wrapper 到達工具列、按鈕、預覽和頁腳。僅當沒有變數公開您需要的內容時才使用類別名稱。
1 2 3 4 5 | /* Variables set on the wrapper inherit down to every child */ .markdown-editor-wrapper { --border-radius: 12px; /* rounds the editor and its toolbar buttons */ --color-primary: oklch(60% 0.2 30); } |
類別參考
這些類別名稱對於樣式來說是穩定且安全的。
| 班級 | 元素 |
|---|---|
.markdown-editor-wrapper | 包裹整個編輯器的外容器 |
.toolbar | 編輯區域上方的工具列條 |
.markdown-btn | 單獨的工具列按鈕 |
.preview-btn | 預覽/全螢幕切換按鈕 |
.editor-layout | 網格並排容納編輯區域和預覽 |
.textarea-wrapper | 編輯區域周圍的包裝 |
.editor-textarea | 底層文字區域元素 |
.display-layer | 渲染格式化圖層,僅限混合模式 |
.preview-wrapper | 預覽專欄 |
.preview-content | 在預覽中渲染的 Markdown |
.editor-footer | 編輯器下方的狀態列 |
.find-replace-panel | 尋找並取代面板 |
1 2 3 4 5 6 7 8 9 10 | /* Some variables are set by the component on itself, which beats an inherited value. Target the element directly for those. */ .markdown-editor-wrapper .markdown-btn { --btn--font-size: 0.875rem; } /* And use classes for anything no variable exposes */ .markdown-editor-wrapper .toolbar { border-bottom: 2px solid oklch(60% 0.2 30); } |
定位一位編輯者
在一頁上有多個編輯器時,將其中一個編輯器定位為 data-editor。包裝器反映了它的 id <textarea>, 所以 <textarea id="notes"> 給你 [data-editor="notes"]。 id 本身保留在文字區域中,所以 getElementById 繼續工作。
1 2 3 4 | /* one editor only */ [data-editor="notes"] { --border-radius: 0; } |
🪟 全螢幕和分層(z-index)
在全螢幕模式下,編輯器使用 z-index: 10000,這會清除大多數 UI 框架為固定標題和覆蓋層保留的層。如果固定標題或側邊欄仍然覆蓋編輯器,請提高此值。
覆蓋它 --mte-fullscreen-z-index。該值僅適用於全屏,並且會繼承,因此在任何祖先上設置它都會覆蓋其下面的每個編輯器。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | /* every editor on the page */ .markdown-editor-wrapper { --mte-fullscreen-z-index: 20000; } /* one section only - the value inherits down */ #admin-panel { --mte-fullscreen-z-index: 20000; } /* a single editor, by its textarea id */ [data-editor="notes"] { --mte-fullscreen-z-index: 20000; } |
內容API
MarkdownEditor 的核心優勢之一是它保留了底層 <textarea> 完美同步。无论您使用现代 JavaScript 框架还是传统后端(例如 Django、PHP 或 Laravel),工作流程都保持简单且原生。
閱讀和寫作內容
1.本土方式(推薦)
由於編輯器增強了標準文字區域,因此您可以使用熟悉的 DOM 方法。這是無需學習新 API 即可與資料互動的最快方式。
1 2 3 4 5 | // Retrieve content via ID const markdown = document.getElementById('markdown-editor').value; // Set content via ID (The editor UI updates automatically) document.getElementById('markdown-editor').value = "# New Heading Content"; |
2.使用變數引用
如果您有 textarea 元素的引用,則可以直接使用它:不需要特定於庫的 API。
1 2 3 4 5 6 7 | const textarea = document.getElementById('markdown-editor'); // Retrieve content const markdown = textarea.value; // Set content (the editor UI reflects this immediately) textarea.value = "## Updated via JS"; |
3.設定初始內容伺服器端
設定初始內容的建議方法是直接在 <textarea> HTML:這可以自然地與每個後端框架(Django、Laravel、Rails、PHP 等)配合使用,編輯器會在 init 上自動呈現它。
1 2 | <!-- Recommended: set content server-side --> <textarea id="markdown-editor"># Hello World</textarea> |
若要在執行時間讀取或更新內容,請使用本機 textarea 價值。稱呼 editor.render() 更新後刷新預覽和混合層。
1 2 3 4 5 6 7 8 | const textarea = document.getElementById('markdown-editor'); // Read const markdown = textarea.value; // Update at runtime textarea.value = '# New content'; editor.render(); |
4.拆掉編輯器: destroy()
稱呼 editor.destroy() 刪除編輯器 DOM 包裝並恢復原始狀態 <textarea> 到其在文檔中的位置。在單頁應用程式中卸載視圖時很有用。
1 2 3 4 | const editor = new MarkdownEditor('#markdown-editor'); // Remove the editor and restore the plain textarea editor.destroy(); |
對變化做出反應 onChange
透過一個 onChange 每次內容變更時都會收到回呼通知。接收目前的 Markdown 字串。
1 2 3 4 5 | const editor = new MarkdownEditor('#markdown-editor', { onChange(value) { console.log('Content changed:', value.length, 'characters'); } }); |
草稿自動儲存 localStorage
使用 onChange 每次擊鍵時儲存草稿。在初始化編輯器之前透過預先填充文字區域來恢復它。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | const DRAFT_KEY = 'my-page-draft'; // Restore saved draft before init (only if textarea starts empty) const textarea = document.getElementById('markdown-editor'); const saved = localStorage.getItem(DRAFT_KEY); if (saved && !textarea.value) textarea.value = saved; // Save on every change const editor = new MarkdownEditor('#markdown-editor', { onChange(value) { localStorage.setItem(DRAFT_KEY, value); } }); // Clear draft after successful form submission document.querySelector('form').addEventListener('submit', () => { localStorage.removeItem(DRAFT_KEY); }); |
表格提交
因為 MarkdownEditor 是直接建構在原生之上的 <textarea>,它開箱即用,與每個後端框架(Django、Laravel、PHP、Ruby on Rails 等)相容。
這就是「本地優先」理念的閃光點。您無需在提交表單之前手動同步資料。瀏覽器將編輯器視為標準輸入欄位。
1 2 3 4 5 6 7 8 9 10 11 12 | <form method="POST" action="/api/submit"> <textarea id="markdown-editor" name="content" class="h-48" rows="5"> # Initial Content </textarea> <button type="submit">Submit to Server</button> </form> <script> // Just initialize it. That's it. new MarkdownEditor('#markdown-editor'); </script> |
筆記: MarkdownEditor 外掛程式必須初始化
只需使用標準 HTML <form>。這 name 文字區域上的屬性是您的伺服器將用來識別內容的屬性。
🚀 為什麼它會改變後端的遊戲規則
由於編輯器保留了原生 <textarea> 行為,您的伺服器將資料作為標準字串處理。需要零額外邏輯:沒有 preventDefault() 並且沒有說明書 FormData 建造。
💡 為什麼這是一個「殺手級功能」:
大多數編輯器(如 Quill、Editor.js、simpleMDE、easyMDE)以複雜的 JSON 結構保存資料。如果開發人員使用這些,他們必須重寫他們的資料庫模式和渲染邏輯。
使用 MarkdownEditor,開發人員可以使用舊網站,替換普通網站 <textarea> 與您的編輯器一起使用,後端甚至不知道它發生了變化。它只是收到與往常相同的原始文本,但用戶獲得了 10 倍更好的體驗。
| 框架/語言 | 如何存取 Markdown 內容 |
|---|---|
| PHP | $_POST['content'] |
| 薑戈 | request.POST.get('content') |
| Node.js(Express) | req.body.content |
| 拉維爾 | $request->input('content') |
| 紅寶石 on Rails | params[:content] |
🖼️ 高級圖片上傳
本地處理圖像上傳:而不是依賴緩慢、佔用大量記憶體的 Base64 字串,這對於效能和 SEO 來說都是一個重大勝利。
貼上和放置
將螢幕截圖貼到編輯器中或將圖像檔案拖曳到編輯器中,然後透過與工具列按鈕相同的端點上傳。佔位符會立即出現,因此編輯器不會看起來凍結,一旦上傳落地,它就會被替換為真實路徑。如果上傳失敗,佔位符將替換為可見標記,而不是默默消失。
這需要 uploadUrl 配置如下。如果沒有它,貼上圖像不會執行任何操作,並且編輯器會記錄一條警告,解釋要添加的內容,因為替代方案將是資料庫中的 Base64 字串。
一次上傳多個文件,因此圖像按照到達的順序排列。
配置選項
影像工具支援 fileInput 配置來處理直接伺服器上傳。
accept:定義允許的圖像格式陣列(例如“webp”、“avif”)uploadUrl:指定後端端點File對象將透過發送POSTparams:可選對象,用於與映像檔一起傳送附加資料(例如 CSRF 令牌、使用者 ID 或資料夾名稱)
使用範例(完整配置)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | const options = { placeholder: 'Start writing...', toolbar: [ 'link', { image: { fileInput: { accept: ['webp', 'avif'], // restrict the image upload format uploadUrl: '/api/upload', // Your upload endpoint params: { _token: 'your_csrf_token_here', // Essential for Laravel/Django folder: 'blog_posts' } }, // Supports boolean: true/false OR object: { required: true } altInput: { required: true } } }, 'preview' ], } const editor = new MarkdownEditor('#markdown-editor', options); |
📡 伺服器集成
請求
編輯發來一條 POST 請求為 multipart/form-data。預設情況下,它包括:
image_file: 實際的文件對象image_alt:使用者輸入的替代文本- ...加上中定義的任何自訂數據
params目的
所需的回應
若要確認上傳成功並將圖像插入編輯器,您的伺服器必須傳回以下 JSON 結構:
1 2 3 4 | { "success": true, "image_path": "https://cdn.yourdomain.com/uploads/image.webp" } |
注意:確保您使用密鑰 image_path 為上傳圖像的 URL。
您也可以返回 image_alt,僅當使用者將 alt 欄位留空時才用作建議。他們自己輸入的任何內容總是會獲勝,因此從文件名或圖像識別中派生替代文字的伺服器可以在不覆蓋真實描述的情況下提供替代文字。
1 2 3 4 5 | { "success": true, "image_path": "https://cdn.yourdomain.com/uploads/image.webp", "image_alt": "Two people looking at a laptop" } |
失敗時返回 success: false 與一個 error 或者 message 细绳。該文字會呈現給用戶,因此請使其成為他們可以採取行動的內容。
圖像替代文字驗證(altInput)
為了確保您的內容保持可訪問性和 SEO 友善性,MarkdownEditor 預設強制執行替代文字驗證。
- 預設行為:如果
altInput沒有定義,預設為{ required: true } - 強制可訪問性:在提供替代說明之前,將阻止使用者插入圖像
1.預設(無需配置)
1 2 3 4 | // Alt text is REQUIRED by default image: { fileInput: { uploadUrl: '/api/upload' } } |
2.速記(禁用驗證)
如果您想允許沒有描述的圖像,只需將布林值設為 false.
1 2 3 | image: { altInput: false // Users can now skip the alt text field } |
3.基於物件(顯式)
1 2 3 4 5 | image: { altInput: { required: false // Disables alt text validation — users can skip the alt field } } |
標準影像使用(否 fileInput)
如果 fileInput 未配置時,編輯器預設為簡單的基於 URL 的模式。如果您的用戶主要連結到外部圖像主機,那麼這是理想的選擇。
1 2 3 4 5 6 7 8 | const options = { toolbar: [ 'link', 'image', 'preview' ], } const editor = new MarkdownEditor('#markdown-editor', options); |
💡 為什麼要使用參數?
在 Laravel 或 Django 等框架中,如果沒有 CSRF 令牌,則無法上傳檔案。透過添加 _token 到 params 對象,您的請求將無縫地通過後端的安全中間件,維護伺服器端控制器的「零邏輯」概念。
⌨️ 鍵盤快速鍵
常見的格式化操作可以直接從鍵盤觸發,無需觸摸工具列。每個快捷方式也顯示在對應的工具列按鈕的工具提示中。
| 捷徑 | 行動 |
|---|---|
Ctrl + B / ⌘ B | 切換 粗體 |
Ctrl + I / ⌘ I | 切換斜體 |
Ctrl + K / ⌘ K | 插入連結 |
Ctrl + ` / ⌘ ` | 切換內聯 Code |
Ctrl + Shift + S / ⌘ ⇧ S | 切換 |
Ctrl + 1 / ⌘ 1 | 標題 1 |
Ctrl + 2 / ⌘ 2 | 標題 2 |
Ctrl + 3 / ⌘ 3 | 標題 3 |
Ctrl + L / ⌘ L | 切換項目符號列表 |
Ctrl + Z / ⌘ Z | 撤銷 |
Ctrl + Shift + Z / ⌘ ⇧ Z | 重做 |
Tab | 縮排選定的行 |
Shift + Tab | 減少縮排選定的行 |
Ctrl + F / ⌘ F | 打開尋找面板 |
Ctrl + H / ⌘ H | 打開尋找和取代面板 |
Ctrl + Shift + F / ⌘ ⇧ F | 切換全螢幕預覽 |
F11 | 切換全螢幕預覽 |
Escape | 關閉查找面板/退出全螢幕預覽 |
🔍 尋找和替換
編輯器內提供內建尋找和取代面板:無需瀏覽器擴充功能或單獨的工具。
- 按
Ctrl + F(或者⌘ F) 開啟 尋找 面板 - 按
Ctrl + H(或者⌘ H) 開啟 尋找並取代 面板 - 搜尋不區分大小寫並顯示即時比賽計數器(例如 3 of 12)
- 使用 ▲ / ▼ 按鈕導覽匹配或
Enter/Shift + Enter - 替換 取代目前反白顯示的符合項目; 全部替換 一次取代所有出現的內容
- 按
Escape關閉面板並將焦點返回編輯器
此面板浮動在編輯器內容區域的右上角,不會中斷寫入。
🔗 來自貼上 URL 的鏈接
選擇一些文本,在其上貼上 URL,然後您會得到一個 Markdown 鏈接,而不是替換您選擇的內容的 URL。
1 2 | Read the docs <- select "the docs", paste https://example.com Read [the docs](https://example.com) <- what you get |
規則刻意嚴格:只有裸露的 http 或者 https 不帶空格的 URL 將以這種方式處理。貼上恰好包含 URL 的句子或在未選擇任何內容的情況下進行粘貼,其行為與普通粘貼類似。
特徵
🔌 原生表單集成
工作原理與標準完全相同 <textarea>。沒有複雜的 API:只需使用 value 或者 name 屬性。它「只適用於」PHP、Django 或 Node.js 中的標準 HTML 表單提交。
🖼️ 高級圖片上傳
透過 API 設定本機伺服器上傳。透過在您自己的 CDN 上託管圖像,避免使用繁重的 Base64 字串,以確保更快的頁面加載和卓越的 SEO。
🔀 混合模式和普通模式
之間切換 混合(所見即所得) 視覺編輯經驗或 普通降價 傳統編碼感覺的模式。
🚀 高性能
一個 gzip 壓縮後大小為 53 KB 捆綁包(縮小為 252 KB,包含 CSS)針對「重內容」進行了最佳化。處理大量文件和大文件,不會出現任何輸入延遲或效能下降。去抖動預覽更新、快取樣式計算和無衝突鍵盤處理:因此 Tab 和 Enter 總是只做一件事。
🌍 內建 RTL 支持
阿拉伯語、烏爾都語和波斯語等從右到左語言的本機支援。非常適合建立全球可訪問的應用程式。
✨ 語法高亮
透過清晰的程式碼和 Markdown 格式增強可讀性。
🌙 自適應主題
包括自動深色模式支援。它與您的系統設定或 水果果醬使用者介面 圖書館提供無縫的視覺體驗。
📝 智能編輯
GitHub 風格的自動清單延續,適用於有序清單、無序列表和清單:按 Enter 編輯繼續這個模式。預覽窗格中的核取方塊可點選並立即同步回 Markdown 來源。
📱 完全響應
流暢、行動優先的使用者介面,完美適應桌上型電腦、平板電腦和智慧型手機,隨時隨地進行編輯。
📦 普遍支持
相容於 ESM、UMD、CommonJS 和 IIFE。透過 CDN 開箱即用(<script src>)、npm 或任何捆綁器(Vite、webpack、Rollup):無需額外配置。
♿ 預設可訪問
內建完整的 ARIA 支援:工具列地標、標籤的預覽區域、螢幕閱讀器友善的按鈕、 aria-pressed 在預覽開關上, disabled 和 aria-disabled 在非活動工具上,並在模式關閉時正確恢復焦點。
🛡️ 零 CSS 衝突
編輯器樣式完全適用於 .markdown-editor-wrapper。 Tailwind 的全域預檢被排除,因此編輯器可以安全地與 Bootstrap、Tailwind 或任何其他框架一起使用,而不會破壞它們的風格。
⌨️ 鍵盤快速鍵
Ctrl+B, Ctrl+I, Ctrl+K, Ctrl+`, Ctrl+Shift+S:無需觸碰滑鼠的常見格式化操作。每個快捷方式都顯示在工具列按鈕的工具提示中。
🔍 尋找和替換
按 Ctrl+F 尋找或 Ctrl+H 打開尋找和取代。不區分大小寫的搜索,具有即時匹配計數器、下一個/上一個導航、單一替換和全部替換:無需離開編輯器。
🔒 XSS 安全預覽
渲染的預覽透過以下方式進行清理 DOM純化 在寫入 DOM 之前。精心設計的 Markdown 輸入中的腳本標籤、內聯事件處理程序和惡意 URL 都會自動刪除:無需配置。
▶️即時預覽
在您鍵入時查看立即呈現的 Markdown。
🔗 輕鬆集成
只需最少的設定即可無縫整合到任何 Web 專案中。
🛠️ 可自訂的工具列
動態配置和重新排序工具列選項,例如粗體、斜體等。
完整配置範例
使用這個綜合範例來初始化 MarkdownEditor 的所有主要功能,包括自訂工具列排序和進階影像上傳處理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | const editor = new MarkdownEditor('#markdown-editor', { mode: 'hybrid', placeholder: 'Start writing...', footer: { line: true, col: true, chars: true, words: true, }, onChange(value) { console.log('Content updated:', value.length, 'characters'); }, labels: { 'Bold': 'Gras', 'Italic': 'Italique', 'Uploading...': 'Téléversement...', }, toolbar: [ 'heading', 'bold', 'italic', 'strikethrough', 'blockquote', 'ul', 'ol', 'checklist', 'code', 'codeblock', 'hr', 'table', { image: { fileInput: { accept: ['webp', 'avif', 'png'], uploadUrl: '/api/upload' } } }, 'link', 'undo', 'redo', 'indent', 'outdent', 'preview' ], }); // Read content natively const markdown = document.getElementById('markdown-editor').value; // destroy() when the view unmounts (SPAs) // editor.destroy(); |
覺得有用嗎?
GitHub 之星可以幫助其他開發人員發現該編輯器。它是的一部分 弗魯賈姆。那裡的明星也有幫助。