---
title: "Markdown editor"
type: plugin
version: "2.2.2"
doc_version: "2.7.3"
status: stable
date: 2026-07-05
library: Frutjam
stack: tailwind_css
compatibility: universal
framework_agnostic: true
runtime_requirement: none
description: "JavaScript markdown editor plugin for Tailwind CSS projects. WYSIWYG and plain Markdown modes, live preview, RTL support, dark mode. Works with Django, HTMX, Laravel, React."
url: https://frutjam.com/zh-hant/plugins/markdown-editor
---

# The Native-First, High-Performance Markdown Plugin for JavaScript

## 理念：“本土第一”

大多數編輯器都打破了標準的網路工作流程。 **MarkdownEditor** 擁抱它。
由於它直接位於 `</code> 之上，因此您無需學習處理資料的新方法。</p>
<ul>
    <li><strong>無需資料綁定：</strong>開箱即用 <code><form method="POST"></code></li>
    <li><strong>標準存取：</strong>像普通輸入一樣使用<code>document.getElementById('editor').value</code>。</li>
    <li><strong>與後端無關：</strong>可與任何後端（Python、Node.js、PHP 等）配合使用，就像普通表單欄位一樣</li>
</ul>

<h2>主要特點</h2>
<h3>🖼️ 高級圖像上傳（SEO 優化）</h3>
<p>不要使用大量的 Base64 字串來使資料庫膨脹。配置我們的 API 以將圖像直接上傳到您的伺服器或 S3 儲存桶。編輯器接收 URL，讓您的 Markdown 文件保持簡潔，並保持網站的 SEO 排名較高。</p>
<h3>🔀 混合模式和普通模式</h3>
<p>為您的用戶提供兩全其美的服務。在用於輕鬆格式化的<strong>視覺 (WYSIWYG) 混合模式</strong>和用於無幹擾的原始語法編輯的<strong>純 Markdown 模式</strong>之間切換。</p>
<h3>🌍 全球就緒，支援 RTL</h3>
<p>對從右到左 (RTL) 語言的完全本機支援。非常適合需要<strong>阿拉伯語、烏爾都語或波斯語</strong>支援並具有自動文字方向對齊功能的項目。</p>
<h3>⚡ 大規模性能</h3>
<ul>
    <li><strong>輕量級</strong>：佔用空間約 116KB，不會減慢頁面載入速度</li>
    <li><strong>大文件支援</strong>：經過最佳化，可以處理數千行文本，而不會出現輸入延遲或瀏覽器凍結的情況</li>
    <li><strong>智慧型渲染</strong>：去抖動預覽更新、快取樣式計算以及清單延續與縮排之間的無衝突鍵盤處理 - 因此 Tab 和 Enter 總是只做一件事</li>
</ul>
<h3>♿ 預設可訪問</h3>
<p>內建完整的 ARIA 支持，無需額外配置。工具列是一個適當的 <code>role="toolbar"</code> 地標，預覽窗格是一個帶有標籤的 <code>role="region"</code>，所有 SVG 圖標都對屏幕閱讀器隱藏，預覽切換通過 <code>aria-pressed</code> 顯示其開/關狀態，禁用的工具列按鈕模態框關閉時將焦點回到觸發按鈕。</p>
<h3>🛡️ 零 CSS 衝突</h3>
<p>所有編輯器樣式都完全限定在 <code>.markdown-editor-wrapper</code> 元素範圍內。 Tailwind 的全域預檢（<code>h1</code>–<code>h6</code>、<code>a</code>、<code>button</code> 等的元素重置）被排除在外，因此編輯器可以與 Bootstrap、Tailwind 或同一頁面上的任何其他 CSS 框架一起使用，而不會破壞單一樣式。</p>
<h3>🔒 XSS 安全預覽</h3>
<p>渲染的預覽在寫入 DOM 之前會透過 <a href="https://github.com/cure53/DOMPurify" target="_blank">DOMPurify</a> 進行清理。精心設計的 Markdown 輸入中的腳本標籤、內聯事件處理程序和惡意 URL 都會自動刪除——無需配置。</p>

<h2>Markdown 編輯器演示</h2>
<textarea class="hybrid-markdown-editor" rows="5" placeholder="Start writing..."># Markdown Editor

`

## `快速實施`

`

### 1. 安裝

您可以使用NPM安裝，直接匯入JavaScript文件，或使用CDN進行快速部署。

#### 透過 NPM 安裝

```bash
npm install markdown-text-editor
```

或者

#### 使用 CDN

或者，在您的 HTML 中包含以下 CDN 鏈接

```html
<script src="https://cdn.jsdelivr.net/npm/markdown-text-editor"></script>
```

### 2. HTML 結構

只需將 </code> 放入標準表單中即可。無需特殊包裝。</p>

<pre><code class="language-html"><form action="/api/save" method="POST">
  <textarea id="markdown-editor" name="content"># Hello World</textarea>
  <button type="submit">Save Content</button>
</form></code></pre>

<h3>3. 導入 JS 和 CSS 並在 textarea 元素上初始化插件</h3>

<pre><code class="language-javascript">import MarkdownEditor from "markdown-text-editor";

const editor = new MarkdownEditor('#markdown-editor', {
  placeholder: 'Write your markdown...',
  toolbar: ['heading', 'bold', 'italic', 'strikethrough', 'ul', 'ol', 'checklist', 'blockquote', 'link', 'preview'],
});</code></pre>

<h3>4. 配置與客製化</h3>

<p>您可以透過傳遞 <code>options</code> 物件來完全自訂編輯器的行為和介面。如果省略選項，則使用<strong>預設</strong>值。</p>

<div class="overflow-x-auto w-full not-prose">
    <table class="table">
        <thead>
            <tr>
                <th>財產</th>
                <th>類型</th>
                <th>預設</th>
                <th>目的</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td><code>mode</code></td>
                <td><code>string</code></td>
                <td><code>'plain'</code></td>
                <td>設定初始視圖。使用 <code>'hybrid'</code> 獲得所見即所得體驗，或使用 <code>'plain'</code> 取得原始語法。</td>
            </tr>
            <tr>
                <td><code>placeholder</code></td>
                <td><code>string</code></td>
                <td><code>'Write...'</code></td>
                <td>編輯器為空時顯示的文字。</td>
            </tr>
            <tr>
                <td><code>toolbar</code></td>
                <td><code>array</code></td>
                <td><code>[...]</code></td>
                <td>定義顯示哪些工具以及顯示順序。</td>
            </tr>
            <tr>
                <td><code>footer</code></td>
                <td><code>false | object</code></td>
                <td>全部可見</td>
                <td>控制編輯器下方顯示的狀態列。設定為 <code>false</code> 以完全隱藏它，或傳遞一個物件來切換單一統計資訊。</td>
            </tr>
            <tr>
                <td><code>theme</code></td>
                <td><code>string</code></td>
                <td>遺傳</td>
                <td>明確設定編輯器主題（<code>'light'</code>、<code>'dark'</code>、<code>'snowberry'</code>、<code>'darkberry'</code>）。如果省略，編輯器將從最近的祖先元素或 <code><textarea></code> 本身繼承 <code>data-theme</code>。</td>
            </tr>
            <tr>
                <td><code>minHeight</code></td>
                <td><code>number</code></td>
                <td><code>200</code></td>
                <td>當內容較短時，編輯器將縮小到的最小高度（以像素為單位）。與 <code>maxHeight</code> 配對以設定自動增長範圍。</td>
            </tr>
            <tr>
                <td><code>maxHeight</code></td>
                <td><code>number</code></td>
                <td><code>500</code></td>
                <td>編輯器在非全螢幕模式下可以增長到的最大高度（以像素為單位）。一旦內容超過此高度，編輯器內就會出現捲軸。該編輯器還有一個拖曳手柄，因此使用者可以手動將其大小調整到超出此限制。</td>
            </tr>
            <tr>
                <td><code>onChange</code></td>
                <td><code>function</code></td>
                <td><code>undefined</code></td>
                <td>每次內容變更時都會觸發回調 - 鍵入、工具列操作、撤銷/重做和清單延續。接收目前的 markdown 字串作為其唯一的參數。</td>
            </tr>
        </tbody>
    </table>
</div>

<h4>🛠 工具列自訂</h4>
<p>工具列是模組化的。您可以透過修改陣列來創建最低限度的體驗或功能齊全的電源套件。</p>
<h5>可用工具</h5>

<div class="overflow-x-auto w-full not-prose">
    <table class="table">
    <thead>
        <tr>
        <th>類別</th>
        <th>工具鍵</th>
        </tr>
    </thead>
    <tbody>
        <tr>
        <td>版式</td>
        <td><code>heading</code>, <code>bold</code>, <code>italic</code>, <code>strikethrough</code>, <code>blockquote</code></td>
        </tr>
        <tr>
        <td>清單</td>
        <td><code>ul</code> (子彈), <code>ol</code> (編號的), <code>checklist</code></td>
        </tr>
        <tr>
        <td>程式碼</td>
        <td><code>code</code> (排隊), <code>codeblock</code> (圍欄塊)</td>
        </tr>
        <tr>
        <td>刀片</td>
        <td><code>hr</code> (水平線), <code>table</code> (表格模板)</td>
        </tr>
        <tr>
        <td>媒體</td>
        <td><code>link</code>, <code>image</code></td>
        </tr>
        <tr>
        <td>編輯</td>
        <td><code>undo</code>, <code>redo</code>, <code>indent</code>, <code>outdent</code></td>
        </tr>
        <tr>
        <td>看法</td>
        <td><code>preview</code></td>
        </tr>
    </tbody>
    </table>
</div>

<h6>💡實施技巧：</h6>
<ul>
    <li><strong>重新排序</strong>：按鈕會依照您在陣列中列出的確切順序顯示</li>
    <li><strong>刪除</strong>：只需從陣列中省略任何鍵（例如<code>image</code>）即可為使用者完全停用該功能</li>
    <li><strong>原生後備</strong>：如果您未在 JS 中提供 <code>placeholder</code>，外掛程式將自動使用 HTML <code><textarea></code> 中的 <code>placeholder</code> 屬性</li>
</ul>

<h4>📊 頁腳（狀態列）</h4>
<p>頁腳位於編輯器下方，顯示遊標的<strong>行</strong>、<strong>列</strong>、文件的<strong>字元數</strong>以及可選的<strong>字數</strong>——所有這些都是即時更新的。預設情況下它是可見的，並且每個統計資料都可以獨立切換。</p>

<div class="overflow-x-auto w-full not-prose">
    <table class="table">
        <thead>
            <tr>
                <th>鑰匙</th>
                <th>類型</th>
                <th>預設</th>
                <th>描述</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td><code>line</code></td>
                <td><code>boolean</code></td>
                <td><code>true</code></td>
                <td>顯示目前行號。</td>
            </tr>
            <tr>
                <td><code>col</code></td>
                <td><code>boolean</code></td>
                <td><code>true</code></td>
                <td>顯示目前的列號。</td>
            </tr>
            <tr>
                <td><code>chars</code></td>
                <td><code>boolean</code></td>
                <td><code>true</code></td>
                <td>顯示總字元數。</td>
            </tr>
            <tr>
                <td><code>words</code></td>
                <td><code>boolean</code></td>
                <td><code>false</code></td>
                <td>顯示總字數。預設為關閉 — 設定為 <code>true</code> 即可啟用。</td>
            </tr>
        </tbody>
    </table>
</div>

<h5>使用範例</h5>

<pre><code class="language-javascript">// 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 } });</code></pre>

<h3>5. 取得、設定和提交內容</h3>
<p><strong>MarkdownEditor</strong> 的核心優勢之一是它保持底層 <code><textarea></code> 完美同步。無論您使用現代 JavaScript 框架還是傳統後端（例如 Django、PHP 或 Laravel），工作流程都保持簡單且原生。</p>

<h4>1. The Native Way（推薦）</h4>
<p>由於編輯器增強了標準文字區域，因此您可以使用熟悉的 DOM 方法。這是無需學習新 API 即可與資料互動的最快方式。</p>

<pre><code class="language-javascript">// 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";</code></pre>

<h4>2. 使用變數引用</h4>
<p>如果您有對 textarea 元素的引用，則可以直接使用它 - 不需要特定於庫的 API。</p>

<pre><code class="language-javascript">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";</code></pre>

<h4>3. 設定和讀取內容</h4>
<p>設定初始內容的建議方法是直接在 <code><textarea></code> HTML 中 - 這自然適用於每個後端框架（Django、Laravel、Rails、PHP 等），並且編輯器會在 init 時自動呈現它。</p>

<pre><code class="language-html"><!-- Recommended: set content server-side -->
<textarea id="markdown-editor"># Hello World</textarea></code></pre>

<p>若要在執行時間讀取或更新內容，請使用本機 <code>textarea</code> 值。更新後呼叫 <code>editor.render()</code> 以刷新預覽層和混合層。</p>

<pre><code class="language-javascript">const textarea = document.getElementById('markdown-editor');

// Read
const markdown = textarea.value;

// Update at runtime
textarea.value = '# New content';
editor.render();</code></pre>

<h4>4. 拆除編輯器－<code>destroy()</code></h4>
<p>呼叫 <code>editor.destroy()</code> 刪除編輯器 DOM 包裝器並將原始 <code><textarea></code> 還原到其在文件中的位置。在單頁應用程式中卸載視圖時很有用。</p>

<pre><code class="language-javascript">const editor = new MarkdownEditor('#markdown-editor');

// Remove the editor and restore the plain textarea
editor.destroy();</code></pre>

<h5>使用 <code>onChange</code> 回應更改</h5>
<p>傳遞 <code>onChange</code> 回呼以在每次內容變更時收到通知。接收目前的 Markdown 字串。</p>

<pre><code class="language-javascript">const editor = new MarkdownEditor('#markdown-editor', {
    onChange(value) {
        console.log('Content changed:', value.length, 'characters');
    }
});</code></pre>

<h6>使用 <code>localStorage</code> 自動儲存草稿</h6>
<p>使用 <code>onChange</code> 在每次按鍵時儲存草稿。在初始化編輯器之前透過預先填充文字區域來恢復它。</p>

<pre><code class="language-javascript">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);
});</code></pre>

<h4>4. 輕鬆自動提交表單</h4>
<p>由於 <strong>MarkdownEditor</strong> 直接建立在原生 <code><textarea></code> 上，因此它開箱即用，與每個後端框架（Django、Laravel、PHP、Ruby on Rails 等）相容。</p>
<p>這就是「本地優先」理念的閃光點。您無需在提交表單之前手動同步資料。瀏覽器將編輯器視為標準輸入欄位。</p>

<pre><code class="language-html"><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></code></pre>

<p class="text-sm">
  <strong>注意：</strong> MarkdownEditor 外掛程式必須初始化
</p>

<p>只需使用標準 HTML <code><form></code>。文字區域上的 <code>name</code> 屬性是您的伺服器將用來識別內容的屬性。</p>

<h5>🚀 為什麼它會改變後端的遊戲規則</h5>
<p>由於編輯器保留本機 <code><textarea></code> 行為，因此您的伺服器將資料作為標準字串處理。所需的額外邏輯為零，無需 <code>preventDefault()</code> 也無需手動建構 <code>FormData</code>。</p>

<h5>💡 為什麼這是一個「殺手級功能」：</h5>
<p>大多數編輯器（如 Quill、Editor.js、simpleMDE、easyMDE）以複雜的 JSON 結構保存資料。如果開發人員使用這些，他們必須重寫他們的資料庫模式和渲染邏輯。</p>
<p>透過 <strong>MarkdownEditor</strong>，開發人員可以使用舊網站，用編輯器取代普通的 <code><textarea></code>，而<strong>後端甚至不知道它發生了變化</strong>。它只是收到與往常相同的原始文本，但用戶獲得了 10 倍更好的體驗。</p>

<div class="overflow-x-auto w-full">
    <table class="table table-xs not-prose">
    <thead>
        <tr>
        <th>框架/語言</th>
        <th>如何存取 Markdown 內容</th>
        </tr>
    </thead>
    <tbody>
        <tr>
        <td>PHP</td>
        <td>$_POST['content']</td>
        </tr>
        <tr>
        <td>Django</td>
        <td>request.POST.get('content')</td>
        </tr>
        <tr>
        <td>Node.js (Express)</td>
        <td>req.body.content</td>
        </tr>
        <tr>
        <td>Laravel</td>
        <td>$request->input('content')</td>
        </tr>
        <tr>
        <td>Ruby on Rails</td>
        <td>params[:content]</td>
        </tr>
    </tbody>
    </table>
</div>

<h2>配置選項</h2>

<h3>🖼️高級圖片上傳</h3>
<p>本地處理圖像上傳（而不是依賴緩慢且佔用大量記憶體的 Base64 字串）對於效能和 SEO 來說都是一個重大勝利。</p>
<h4>配置選項</h4>
<p>圖像工具支援 <code>fileInput</code> 配置來處理直接伺服器上傳。</p>
<ul>
    <li><code>accept</code>：定義允許的影像格式陣列（例如「webp」、「avif」）</li>
    <li><code>uploadUrl</code>：指定將透過 <code>POST</code> 傳送 <code>File</code> 物件的後端端點</li>
    <li><code>params</code>：可選對象，用於與映像檔一起傳送附加資料（例如 CSRF 令牌、使用者 ID 或資料夾名稱）</li>
</ul>
<!-- <p>After a successful upload, the server must return the image path, which will be automatically populated in the URL field</p> -->
<h4>使用範例（完整配置）</h4>

<pre><code class="language-javascript">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);</code></pre>

<h4>📡 伺服器整合詳細信息</h4>
<h5>1. 請求</h5>
<p>編輯器以 <code>multipart/form-data</code> 形式傳送 <code>POST</code> 請求。預設情況下，它包括：</p>
<ul>
    <li><code>image_file</code>：實際的文件對象</li>
    <li><code>image_alt</code>：使用者輸入的替代文本</li>
    <li>...加上 <code>params</code> 物件中定義的任何自訂數據</li>
</ul>

<h5>2. 所需的回應</h5>
<p>若要確認上傳成功並將映像插入編輯器，您的伺服器<strong>必須</strong>傳回以下 JSON 結構：</p>

<pre><code class="language-json">{
  "success": true,
  "image_path": "https://cdn.yourdomain.com/uploads/image.webp"
}</code></pre>

<p><strong>注意</strong>：確保使用 <code>image_path</code> 鍵作為上傳圖像的 URL。</p>

<h4>圖像替代文字驗證 (<code>altInput</code>)</h4>
<p>為了確保您的內容保持可訪問性和 SEO 友善性，<code>MarkdownEditor</code> 預設會強制執行替代文字驗證。您可以使用布林簡寫或詳細物件來配置此行為。</p>

<ul>
    <li><strong>預設行為</strong>：如果未定義<code>altInput</code>，則預設為<code>{ required: true }</code></li>
    <li><strong>強制輔助使用</strong>：在提供替代說明之前，使用者將無法插入影像</li>
</ul>

<h5>設定範例：</h5>

<h6>1.預設（無需配置）</h6>

<pre><code class="language-javascript">// Alt text is REQUIRED by default
image: {
  fileInput: { uploadUrl: '/api/upload' }
}</code></pre>

<h6>2. 速記（禁用驗證）</h6>
<p>如果您想允許沒有描述的圖像，只需將布林值設為 <code>false</code> 即可。</p>

<pre><code class="language-javascript">image: {
  altInput: false // Users can now skip the alt text field
}</code></pre>

<h6>3. 基於物件（顯）</h6>

<pre><code class="language-javascript">image: {
    altInput: {
        required: false // Disables alt text validation — users can skip the alt field
    }
}</code></pre>

<h4>標準影像使用（無<code>fileInput</code>）：</h4>
<p>如果未配置 <code>fileInput</code>，則編輯器預設為簡單的基於 URL 的模式。如果您的用戶主要連結到外部圖像主機，那麼這是理想的選擇。</p>

<pre><code class="language-javascript">const options = {
  toolbar: [
    'link',
    'image',
    'preview'
  ],
}
const editor = new MarkdownEditor('#markdown-editor', options);</code></pre>

<h5>💡 為什麼要使用參數？</h5>
<p>在 Laravel 或 Django 等框架中，如果沒有 CSRF 令牌，則無法上傳檔案。透過將 <code>_token</code> 新增至 <code>params</code> 對象，您的請求將無縫地通過後端的安全中介軟體，從而維護伺服器端控制器的「零邏輯」理念。</p>

<h3>🔀 編輯模式</h3>
<p><strong>MarkdownEditor</strong> 提供兩種不同的方式來撰寫和格式化內容。您可以在傳統的以語法為中心的視圖或現代的視覺優先體驗之間切換。</p>

<h4>配置</h4>
<p>您可以在初始化期間使用 <code>mode</code> 屬性定義啟動模式。</p>
<ul>
    <li><code>plain</code>（<strong>預設</strong>）：乾淨、高效能的 Markdown 環境，其中語法（如 <code>**bold**</code> 或 <code># header</code>）可見。開發人員和 Markdown 純粹主義者的理想選擇</li>
    <li><code>hybrid</code>：所見即所得的體驗，可在您鍵入時即時呈現格式（粗體、斜體、標題），同時仍保持底層 Markdown 結構。</li>
</ul>

<h5>執行：</h5>

<pre><code class="language-javascript">// 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'
});</code></pre>

<h5>混合和普通模式預覽：</h5>

<h6>混合模式</h6>
<p>當您鍵入時，視覺格式會即時呈現。</p>
<textarea class="hybrid-markdown-editor mb-4" rows="5" placeholder="Start writing..."># Hybrid mode markdown editor
This will render visual styles immediately.

###### 普通模式（預設）

專注於原始 Markdown 語法以提供輕量級體驗。

# Plain mode markdown editor
This shows the raw **syntax**.

  

| 配置                                                                                       | 財產/工具                                                   | 描述                                                                                                                                                      |
| ---------------------------------------------------------------------------------------- | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 選項對象                                                                                     | placeholder                                             | 設定文字區域的佔位符文字（可選，因為您也可以使用標準 HTML 文字區域屬性）                                                                                                                 |
|                                                                                          | mode: 'hybrid'                                          | 實現所見即所得的體驗，在您鍵入時即時呈現格式（粗體、斜體、標題）                                                                                                                        |
| 工具列：決定工具列中顯示的工具   及其順序。                                                                  | 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 鍵退出全螢幕。 |
| [高級圖像上傳功能](#advanced-image-upload)：   允許配置圖像上傳到   您自己的伺服器並透過 API 設定圖像   路徑。這可以提高效能和 SEO。 | fileInput                                               | accept：允許的映像檔類型陣列（例如'webp'、'avif'）。                         uploadUrl：透過 POST 傳送檔案的後端端點。                         params：額外資料的可選物件（CSRF 令牌、使用者 ID、資料夾名稱） |
|                                                                                          | altInput                                                | required: false：停用替代文字輸入驗證（預設為 true）                                                                                                                    |

### ⌨️ 鍵盤快速鍵

常見的格式化操作可以直接從鍵盤觸發，無需觸摸工具列。每個快捷方式也顯示在對應的工具列按鈕的工具提示中。

  

| 捷徑                         | 行動             |
| -------------------------- | -------------- |
| Ctrl + B  /  ⌘ B           | 切換粗體           |
| Ctrl + I  /  ⌘ I           | 切換斜體           |
| Ctrl + K  /  ⌘ K           | 插入連結           |
| Ctrl + `  /  ⌘ `           | 切換內聯代碼         |
| Ctrl + Shift + S  /  ⌘ ⇧ S | 切換刪除線          |
| Ctrl + Z  /  ⌘ Z           | 撤銷             |
| Ctrl + Shift + Z  /  ⌘ ⇧ Z | 重做             |
| Tab                        | 縮排選定的行         |
| Shift + Tab                | 減少縮排選定的行       |
| Ctrl + F  /  ⌘ F           | 打開尋找面板         |
| Ctrl + H  /  ⌘ H           | 打開尋找和取代面板      |
| Escape                     | 關閉查找面板/退出全螢幕預覽 |

### 🔍 找出並找到代替

編輯器內提供內建尋找和取代面板 - 無需瀏覽器擴充功能或單獨的工具。

- 按下 Ctrl + F（或 ⌘ F）開啟尋找面板
- 按Ctrl + H（或⌘ H）開啟尋找和尋找視窗。更換面板

    - 搜尋不區分大小寫並顯示即時比賽計數器（例如3 / 12）

    - 使用 ▲ / ▼ 按鈕或 Enter / Shift + Enter 導覽匹配項

    - 替換替換目前反白顯示的匹配項； 全部替換一次替換所有出現的內容

    - 按 Escape 關閉面板並將焦點返回編輯器

此面板浮動在編輯器內容區域的右上角，不會中斷寫入。

### 🌙 主題化

MarkdownEditor 自動從周圍頁面繼承其主題 - 無需配置。編輯器在初始化時從最近的祖先讀取data-theme，因此它與您網站的主題保持同步。

#### 主題如何解決（優先順序）

1. theme option - 在選項物件中傳遞的明確覆蓋
2. </code></strong> 上的 <strong><code>data-theme</code> — 直接在元素上設置</li>
    <li>任何祖先的<strong><code>資料主題</code></strong> - 例如<code><html></code>、<code><body></code> 或包裝 <code><div></code></li>
</ol>

    <h4>可用主題</h4>
<p><code>'light'</code>（預設）、<code>'dark'</code>、<code>'snowberry'</code>、<code>'darkberry'</code></p>

    <h5>選項 1 — 從 <code><html></code> 或任何祖先繼承（零配置）</h5>

    <pre><code class="language-html"><html data-theme="dark">
  ...
  <textarea id="markdown-editor"></textarea>
  <script>
    new MarkdownEditor('#markdown-editor'); // picks up dark automatically
  </script></code></pre>

  

    <h5>選項 2 — 直接在 <code><textarea></code> 上設定 <code>data-theme</code></h5>

    <pre><code class="language-html"><textarea id="markdown-editor" data-theme="dark"></textarea>
<script>
  new MarkdownEditor('#markdown-editor');
</script></code></pre>

  

    <h5>選項 3 — 明確的 <code>theme</code> 選項（覆蓋所有內容）</h5>

    <pre><code class="language-javascript">new MarkdownEditor('#markdown-editor', {
    theme: 'dark'
});</code></pre>

  

    <h4>🎨 透過 CSS 變數自訂主題</h4>
<p>您可以透過覆寫 <code>.markdown-editor-wrapper</code> 元素或任何 <code>[data-theme]</code> 選擇器上的 CSS 變數來完全自訂編輯器的外觀。所有顏色均使用 <a href="https://oklch.com" target="_blank">OKLCH 色彩空間</a> 以獲得統一的感知結果。</p>

    <div class="overflow-x-auto w-full not-prose">
    <table class="table table-sm">
        <thead>
            <tr>
                <th>多變的</th>
                <th>目的</th>
                <th>淺色預設</th>
                <th>深色預設</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td><code>--color-base</code></td>
                <td>編輯背景</td>
                <td><code>oklch(100% 0 0)</code></td>
                <td><code>oklch(10.9% 0 0)</code></td>
            </tr>
            <tr>
                <td><code>--color-on-base</code></td>
                <td>主要文字顏色</td>
                <td><code>oklch(22% 0 0)</code></td>
                <td><code>oklch(98% 0 0)</code></td>
            </tr>
            <tr>
                <td><code>--color-primary</code></td>
                <td>主要重音（工具列活動，連結）</td>
                <td><code>oklch(51.1% .262 277)</code></td>
                <td><code>oklch(66.4% .184 286)</code></td>
            </tr>
            <tr>
                <td><code>--color-on-primary</code></td>
                <td>原色表面上的文字</td>
                <td><code>oklch(96.2% .018 272)</code></td>
                <td><code>oklch(10% .01 270)</code></td>
            </tr>
            <tr>
                <td><code>--color-secondary</code></td>
                <td>次要口音</td>
                <td><code>oklch(59.1% .293 323)</code></td>
                <td><code>oklch(65% .18 220)</code></td>
            </tr>
            <tr>
                <td><code>--color-accent</code></td>
                <td>反白顯示重音符號（內聯代碼，斜體）</td>
                <td><code>oklch(54.1% .281 293)</code></td>
                <td><code>oklch(75% .18 50)</code></td>
            </tr>
            <tr>
                <td><code>--color-neutral</code></td>
                <td>中性表面（邊界、分隔線）</td>
                <td><code>oklch(15% 0 0)</code></td>
                <td><code>oklch(85% 0 0)</code></td>
            </tr>
            <tr>
                <td><code>--color-error</code></td>
                <td>錯誤狀態顏色</td>
                <td><code>oklch(57.7% .245 27)</code></td>
                <td><code>oklch(60% .22 30)</code></td>
            </tr>
            <tr>
                <td><code>--border-radius</code></td>
                <td>編輯器框架的圓角</td>
                <td colspan="2"><code>0.25rem</code></td>
            </tr>
        </tbody>
    </table>
</div>

    <h5>自訂主題範例</h5>
<p>編輯器初始化後覆蓋 .markdown-editor-wrapper 上的任何變量，或在樣式表中定義自訂 <code>[data-theme]</code> 區塊：</p>

    <pre><code class="language-css">/* 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;
}</code></pre>

  

  

    <pre><code class="language-javascript">new MarkdownEditor('#markdown-editor', { theme: 'brand' });</code></pre>

  

    <ul>
    <li><strong>即時預覽</strong>：在您輸入時查看立即呈現的 Markdown。</li>
    <li><strong>語法突出顯示：</strong>透過清晰的程式碼和 Markdown 格式增強可讀性。</li>
    <li><strong>輕鬆整合</strong>：只需最少的設定即可無縫整合到任何 Web 專案中。</li>
    <li><strong>可自訂工具列</strong>：動態配置和重新排序工具列選項，例如粗體、斜體等。</li>
</ul>

    <h2>特徵</h2>
<div class="grid lg:grid-cols-3 gap-4 not-prose">
    <div class="card card-sm card-outline">
        <div class="card-content">
            <h2 class="card-title">🔌 原生表單集成</h2>
            <p class="para-sm">工作原理與標準 <code><textarea></code> 完全相同。沒有複雜的 API — 只需使用 <code>value</code> 或 <code>name</code> 屬性。它「只適用於」PHP、Django 或 Node.js 中的標準 HTML 表單提交。</p>
        </div>
    </div>

    <div class="card card-sm card-outline">
        <div class="card-content">
            <h2 class="card-title">🖼️ 高級圖片上傳</h2>
            <p class="para-sm">透過 API 設定本機伺服器上傳。透過在您自己的 CDN 上託管圖像，避免使用繁重的 Base64 字串，以確保更快的頁面加載和卓越的 SEO。</p>
        </div>
    </div>

    <div class="card card-sm card-outline">
        <div class="card-content">
            <h2 class="card-title">🔀 混合模式和普通模式</h2>
            <p class="para-sm">在用於視覺化編輯的<strong>混合 (WYSIWYG)</strong> 體驗和用於傳統編碼感覺的<strong>純 Markdown</strong> 模式之間切換。</p>
        </div>
    </div>

    <div class="card card-sm card-outline">
        <div class="card-content">
            <h2 class="card-title">🚀 高性能</h2>
            <p class="para-sm">一個針對「重內容」進行最佳化的小型 <strong>~116KB</strong> 捆綁包。處理大量文件和大文件，不會出現任何輸入延遲或效能下降。</p>
        </div>
    </div>

    <div class="card card-sm card-outline">
        <div class="card-content">
            <h2 class="card-title">🌍 內建 RTL 支持</h2>
            <p class="para-sm">阿拉伯語、烏爾都語和波斯語等從右到左語言的本機支援。非常適合建立全球可訪問的應用程式。</p>
        </div>
    </div>

    <div class="card card-sm card-outline">
        <div class="card-content">
            <h2 class="card-title">🌙 自適應主題</h2>
            <p class="para-sm">包括自動深色模式支援。它與您的系統設定或 <strong>Frutjam UI</strong> 庫同步，以提供無縫的視覺體驗。</p>
        </div>
    </div>

    <div class="card card-sm card-outline">
        <div class="card-content">
            <h2 class="card-title">📝 智能編輯</h2>
            <p class="para-sm">GitHub 風格的自動清單延續，適用於有序清單、無序列表和清單 - 按 Enter 鍵，編輯器將繼續該模式。預覽窗格中的核取方塊可點選並立即同步回 Markdown 來源。</p>
        </div>
    </div>

    <div class="card card-sm card-outline">
        <div class="card-content">
            <h2 class="card-title">📱 完全響應</h2>
            <p class="para-sm">流暢、行動優先的使用者介面，完美適應桌上型電腦、平板電腦和智慧型手機，隨時隨地進行編輯。</p>
        </div>
    </div>

    <div class="card card-sm card-outline">
        <div class="card-content">
            <h2 class="card-title">📦 普遍支持</h2>
            <p class="para-sm">與<strong>ESM、UMD、CommonJS 和 IIFE</strong> 相容。透過 CDN (<code><script src></script></code>)、npm 或任何捆綁器（Vite、webpack、Rollup）開箱即用 — 無需額外配置。</p>
        </div>
    </div>

    <div class="card card-sm card-outline">
        <div class="card-content">
            <h2 class="card-title">♿ 預設可訪問</h2>
            <p class="para-sm">內建完整的 ARIA 支援 - 工具列地標、帶標籤的預覽區域、螢幕閱讀器友好的按鈕、預覽切換上的 <code>aria-pressed</code>、非活動工具上的 <code>disabled</code> 和 <code>aria-disabled</code>，以及模態關閉時正確的焦點恢復。</p>
        </div>
    </div>

    <div class="card card-sm card-outline">
        <div class="card-content">
            <h2 class="card-title">🛡️ 零 CSS 衝突</h2>
            <p class="para-sm">編輯器樣式的範圍完全限於 <code>.markdown-editor-wrapper</code>。 Tailwind 的全域預檢被排除，因此編輯器可以安全地與 Bootstrap、Tailwind 或任何其他框架一起使用，而不會破壞它們的風格。</p>
        </div>
    </div>

    <div class="card card-sm card-outline">
        <div class="card-content">
            <h2 class="card-title">⌨️ 鍵盤快速鍵</h2>
            <p class="para-sm"><code>Ctrl+B</code>、<code>Ctrl+I</code>、<code>Ctrl+K</code>、<code>Ctrl+`</code>、<code>Ctrl+Shift+S</code> — 無需觸碰滑鼠的常見格式化操作。每個快捷方式都顯示在工具列按鈕的工具提示中。</p>
        </div>
    </div>

    <div class="card card-sm card-outline">
        <div class="card-content">
            <h2 class="card-title">🔍 找出並找到代替</h2>
            <p class="para-sm">按 <code>Ctrl+F</code> 進行尋找或按<code>Ctrl+H</code> 開啟尋找&代替。不區分大小寫的搜索，具有即時匹配計數器、下一個/上一個導航、單一替換和全部替換 - 無需離開編輯器。</p>
        </div>
    </div>
</div>

    <h2>完整配置範例</h2>
<p>使用這個綜合範例來初始化 <strong>MarkdownEditor</strong> 的所有主要功能，包括自訂工具列排序和進階映像上傳處理。</p>

    <pre><code class="language-javascript">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');
    },
    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;

    // Update content programmatically (dispatch input to keep preview in sync)
// const ta = document.getElementById('markdown-editor');
// ta.value = '# New content';
// ta.dispatchEvent(new Event('input', { bubbles: true }));

    // destroy() when the view unmounts (SPAs)
// editor.destroy();</code></pre>

  

  

`

