JavaScript용 네이티브 우선 고성능 마크다운 플러그인
마지막 업데이트:
기본 텍스트 영역을 전체 편집 제품군으로 변환하는 마크다운 텍스트 편집기 플러그인 — 동기화가 필요하지 않습니다. WYSIWYG 및 일반 마크다운 모드, 실시간 미리보기, 찾기 및 바꾸기, RTL 지원, 다크 모드. Django, Laravel, Rails, Node.js, PHP 및 모든 스택에서 작동합니다.
철학: "네이티브 우선"
대부분의 편집자는 표준 웹 작업흐름을 깨뜨립니다. MarkdownEditor는 이를 수용합니다.
<textarea> 바로 위에 위치하므로 데이터를 처리하는 새로운 방법을 배울 필요가 없습니다.
- 데이터 바인딩 필요 없음: 기본적으로
<form method="POST">와 함께 작동 - 일반 액세스: 일반 입력과 마찬가지로
document.getElementById('editor').value를 사용하세요. - 백엔드 불가지론: 일반 양식 필드처럼 모든 백엔드(Python, Node.js, PHP 등)에서 작동합니다.
MarkdownEditor 대 EasyMDE/SimpleMDE
대부분의 JavaScript 마크다운 편집기(EasyMDE, SimpleMDE, CodeMirror 기반 편집기) - <textarea>를 사용자 정의 요소로 대체합니다. 이는 양식 제출이 중단되고 .value가 아무것도 반환하지 않으며 콘텐츠를 다시 읽으려면 추가 코드를 작성해야 함을 의미합니다. MarkdownEditor는 다릅니다. — 기존 텍스트 영역을 향상시키고 대체하지 않습니다.
| 특징 | 마크다운편집기 | EasyMDE / SimpleMDE |
|---|---|---|
| 기본 텍스트 영역이 보존됨 | ✅ | ❌ 교체됨 |
| 양식 제출은 있는 그대로 작동합니다. | ✅ | ❌ 추가 JS가 필요합니다 |
.value를 통해 값 가져오기/설정 |
✅ | ❌ 맞춤 API가 필요함 |
| WYSIWYG 하이브리드 모드 | ✅ | ❌ |
| 내장된 찾기 및 바꾸기 | ✅ | ❌ |
| RTL 지원 | ✅ | ❌ |
| CSP 호환(인라인 JS 없음) | ✅ | ❌ |
| CSS 충돌 없음 | ✅ | ❌ |
| 다크 모드/테마 | ✅ | 제한된 |
| 번들 크기 | ~116KB | ~300KB+ |
프레임워크 통합
MarkdownEditor는 기본 <textarea>를 유지하므로 추가 코드 없이 모든 백엔드 프레임워크와 통합됩니다. 귀하의 서버는 표준 양식 필드에서와 마찬가지로 마크다운 콘텐츠를 받습니다.
Django
텍스트 영역 위젯에 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 |
Laravel
클래스와 함께 f.text_area 사용 — $request->input('content')는 마크다운을 직접 받습니다.
1 2 | <textarea name="content" class="markdown-editor">{{ old('content') }}</textarea> <script>new MarkdownEditor('.markdown-editor');</script> |
루비 온 레일즈
기본적으로 form_with와 함께 작동합니다. — params[:content]에는 마크다운이 포함되어 있습니다. 터보 드라이브의 경우 DOMContentLoaded 대신 turbo:load를 사용하세요.
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/익스프레스
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> |
주요 특징
🖼️ 고급 이미지 업로드(SEO 최적화)
무거운 Base64 문자열로 데이터베이스를 부풀리지 마십시오. 서버 또는 S3 버킷에 이미지를 직접 업로드하도록 API를 구성하세요. 편집자는 URL을 수신하여 Markdown 파일을 가볍게 유지하고 사이트의 SEO 순위를 높게 유지합니다.
🔀 하이브리드 및 일반 모드
사용자에게 두 가지 장점을 모두 제공하세요. 서식을 쉽게 지정할 수 있는 시각적(WYSIWYG) 하이브리드 모드와 방해받지 않는 원시 구문 편집을 위한 일반 마크다운 모드 사이를 전환하세요.
🌍 RTL 지원을 통한 글로벌 지원
RTL(Right-to-Left) 언어에 대한 완벽한 기본 지원. 자동 텍스트 방향 정렬을 통해 아랍어, 우르두어, 페르시아어 지원이 필요한 프로젝트에 적합합니다.
⚡ 규모에 따른 성능
- 경량: 페이지 로드 속도를 늦추지 않는 작은 ~116KB의 공간
- 대용량 문서 지원: 입력 지연이나 브라우저 정지 없이 수천 줄의 텍스트를 처리하도록 최적화되었습니다.
- 스마트 렌더링: 디바운스된 미리보기 업데이트, 캐시된 스타일 계산, 목록 연속과 들여쓰기 간의 충돌 없는 키보드 처리 — 따라서 Tab과 Enter는 항상 정확히 한 가지 작업을 수행합니다.
♿ 기본적으로 액세스 가능
전체 ARIA 지원이 내장되어 있으며 추가 구성이 필요하지 않습니다. 도구 모음은 적절한 role="toolbar" 랜드마크이고, 미리보기 창은 role="region" 라벨이 지정되어 있으며, 모든 SVG 아이콘은 화면 판독기에서 숨겨지고, 미리보기 토글은 aria-pressed를 통해 켜짐/꺼짐 상태를 표시하며, 비활성화된 도구 모음 버튼은 disabled 및 aria-disabled를 모두 사용하므로 보조 기술이 결코 오해되지 않습니다. 모달은 닫히면 트리거 버튼으로 포커스를 되돌립니다.
🛡️ CSS 충돌 없음
모든 편집기 스타일은 .markdown-editor-wrapper 요소로 완전히 범위가 지정됩니다. Tailwind의 전역 프리플라이트(h1–h6, a, button 등에 대한 요소 재설정)가 제외되므로 편집기는 단일 스타일을 손상시키지 않고 동일한 페이지에서 Bootstrap, Tailwind 또는 기타 CSS 프레임워크와 함께 사용할 수 있습니다.
🔒 XSS 안전 미리보기
렌더링된 미리보기는 DOM에 기록되기 전에 DOMPurify를 통해 삭제됩니다. 조작된 마크다운 입력의 스크립트 태그, 인라인 이벤트 핸들러 및 악성 URL은 자동으로 제거되므로 구성이 필요하지 않습니다.
마크다운 편집기 데모
빠른 구현
1. 설치
NPM(번들러: Vite, webpack, Rollup 등)
npm install markdown-text-editor |
1 2 | import MarkdownEditor from 'markdown-text-editor'; new MarkdownEditor('#markdown-editor'); |
CDN: ES 모듈
1 2 3 4 | <script type="module"> import MarkdownEditor from 'https://cdn.jsdelivr.net/npm/markdown-text-editor/dist/markdown-text-editor.es.js'; 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> |
2. 구성 및 초기화
편집기를 사용자 정의하려면 옵션 객체를 전달하세요. 모든 옵션은 선택 사항입니다. 기본값을 사용하려면 모두 생략하세요.
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'], }); |
마크다운 편집기를 즐겨 사용하시나요?
2초 정도 소요되며 프로젝트 성장에 도움이 됩니다. 이는 무료 Tailwind CSS 구성 요소 라이브러리인 Frutjam의 일부입니다. 별표도 도움이 됩니다.
4. 구성 및 사용자 정의
options 객체를 전달하여 편집기의 동작과 인터페이스를 완전히 사용자 정의할 수 있습니다. 옵션을 생략하면 기본값 값이 사용됩니다.
| 재산 | 유형 | 기본 | 목적 |
|---|---|---|---|
mode |
string |
'plain' |
초기 보기를 설정합니다. WYSIWYG 환경에는 하이브리드를 사용하고 원시 구문에는 일반을 사용하세요. |
placeholder |
string |
'Write...' |
편집기가 비어 있을 때 표시되는 텍스트입니다. |
toolbar |
array |
[...] |
표시되는 도구와 순서를 정의합니다. |
footer |
false | object |
모두 보이는 | 편집기 아래에 표시되는 상태 표시줄을 제어합니다. 완전히 숨기려면 false로 설정하고, 개별 통계를 전환하려면 개체를 전달하세요. |
theme |
string |
물려받은 | 편집기 테마(밝음, 어두움, 스노우베리, 다크베리)를 명시적으로 설정합니다. 생략하면 편집기는 가장 가까운 상위 요소 또는 <textarea> 자체에서 data-theme를 상속합니다. |
minHeight |
number |
200 |
콘텐츠가 짧을 때 편집기가 축소되는 최소 높이(픽셀)입니다. maxHeight와 쌍을 이루어 자동 성장 범위를 설정합니다. |
maxHeight |
number |
500 |
전체 화면이 아닌 모드에서 편집기가 확장될 수 있는 최대 높이(픽셀)입니다. 콘텐츠가 이 높이를 초과하면 편집기 내부에 스크롤 막대가 나타납니다. 편집기에는 드래그 핸들도 있어 사용자가 이 제한을 초과하여 수동으로 크기를 조정할 수 있습니다. |
onChange |
function |
undefined |
입력, 도구 모음 작업, 실행 취소/다시 실행, 목록 연속 등 콘텐츠가 변경될 때마다 콜백이 실행됩니다. 현재 마크다운 문자열을 유일한 인수로 받습니다. |
🛠 도구 모음 사용자 정의
도구 모음은 모듈식입니다. 어레이를 수정하여 최소한의 경험이나 모든 기능을 갖춘 전원 제품군을 만들 수 있습니다.
사용 가능한 도구
| 범주 | 도구 키 |
|---|---|
| 타이포그래피 | heading, bold, italic, strikethrough, blockquote |
| 기울기 | ul (총알), ol (번호가 매겨진), checklist |
| 암호 | code (인라인), codeblock (울타리 블록) |
| 인서트 | hr (수평선), table (테이블 템플릿) |
| 메디아 | link, image |
| 편집 | undo, redo, indent, outdent |
| 보다 | preview |
💡 구현 팁:
- 재정렬: 버튼은 배열에 나열된 정확한 순서대로 나타납니다.
- 제거: 사용자에 대해 해당 기능을 완전히 비활성화하려면 배열에서 키(예:
image)를 생략하기만 하면 됩니다. - 네이티브 폴백: JS에서
placeholder를 제공하지 않으면 플러그인이 자동으로 HTML<textarea>의placeholder속성을 사용합니다.
📊 바닥글(상태 표시줄)
바닥글은 편집기 아래에 위치하며 커서의 줄, 열, 문서의 문자 수 및 선택적으로 단어 수를 표시하며 모두 실시간으로 업데이트됩니다. 이는 기본적으로 표시되며 각 통계는 독립적으로 전환될 수 있습니다.
| 열쇠 | 유형 | 기본 | 설명 |
|---|---|---|---|
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 } }); |
5. 콘텐츠 가져오기, 설정 및 제출
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 등)에서 자연스럽게 작동하며 편집기는 초기화 시 이를 자동으로 렌더링합니다.
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 콜백을 전달하세요. 현재 마크다운 문자열을 받습니다.
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); }); |
4. 간편한 자동 양식 제출
MarkdownEditor는 기본 <textarea>에 직접 구축되므로 모든 백엔드 프레임워크(Django, Laravel, PHP, Ruby on Rails 등)와 즉시 호환됩니다.
'네이티브 퍼스트(Native-First)' 철학이 빛을 발하는 곳입니다. 양식을 제출하기 전에 데이터를 수동으로 동기화할 필요가 없습니다. 브라우저는 편집기를 표준 입력 필드와 똑같이 처리합니다.
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배 더 나은 경험을 얻습니다.
| 프레임워크/언어 | 마크다운 콘텐츠에 액세스하는 방법 |
|---|---|
| PHP | $_POST['content'] |
| Django | request.POST.get('content') |
| Node.js (Express) | req.body.content |
| Laravel | $request->input('content') |
| Ruby on Rails | params[:content] |
구성 옵션
🖼️ 고급 이미지 업로드
느리고 메모리 사용량이 많은 Base64 문자열에 의존하지 않고 기본적으로 이미지 업로드를 처리하는 것은 성능과 SEO 모두에 있어 중요한 이점입니다.
구성 옵션
이미지 도구는 직접 서버 업로드를 처리하기 위해 fileInput 구성을 지원합니다.
accept: 허용되는 이미지 형식의 배열을 정의합니다(예: 'webp', 'avif')uploadUrl:POST를 통해File객체가 전송될 백엔드 엔드포인트를 지정합니다.params: 이미지 파일과 함께 추가 데이터(예: CSRF 토큰, 사용자 ID 또는 폴더 이름)를 보내는 선택적 개체입니다.
사용예(Full Config)
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); |
📡 서버 통합 세부정보
1. 요청
편집기는 multipart/form-data로 POST 요청을 보냅니다. 기본적으로 다음이 포함됩니다.
image_file: 실제 파일 객체image_alt: 사용자가 입력한 대체 텍스트- ...그리고
params객체에 정의된 모든 맞춤 데이터
2. 필수 응답
성공적인 업로드를 확인하고 이미지를 편집기에 삽입하려면 서버가 반드시 다음 JSON 구조를 반환해야 합니다.
1 2 3 4 | { "success": true, "image_path": "https://cdn.yourdomain.com/uploads/image.webp" } |
참고: 업로드된 이미지의 URL에 image_path 키를 사용해야 합니다.
이미지 대체 텍스트 유효성 검사(altInput)
콘텐츠에 대한 접근성과 SEO 친화적인 상태를 유지하기 위해 MarkdownEditor는 기본적으로 대체 텍스트 유효성 검사를 시행합니다. 부울 약칭이나 자세한 개체를 사용하여 이 동작을 구성할 수 있습니다.
- 기본 동작:
altInput이 정의되지 않은 경우 기본값은{ 필수: 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 토큰 없이는 파일을 업로드할 수 없습니다. params 개체에 _token을 추가하면 요청이 백엔드의 보안 미들웨어를 원활하게 통과하여 서버 측 컨트롤러에 대한 "제로 로직" 철학을 유지하게 됩니다.
🔀 편집 모드
MarkdownEditor는 콘텐츠를 작성하고 형식을 지정하는 두 가지 방법을 제공합니다. 기존 구문 중심 보기 또는 현대적인 시각적 우선 환경 간에 전환할 수 있습니다.
구성
초기화 중에 mode 속성을 사용하여 시작 모드를 정의할 수 있습니다.
일반(기본값): 구문(예:**bold**또는# 머리글)이 표시되는 깔끔한 고성능 마크다운 환경입니다. 개발자와 Markdown 순수주의자에게 이상적하이브리드: 기본 마크다운 구조를 유지하면서 입력할 때 서식(굵게, 기울임꼴, 제목)을 실시간으로 렌더링하는 WYSIWYG에서 영감을 받은 환경입니다.
구현:
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 구문에 중점을 둡니다.
| 구성 | 속성/도구 | 설명 |
|---|---|---|
| 옵션 개체 | placeholder |
텍스트 영역에 대한 자리 표시자 텍스트를 설정합니다(선택 사항, 표준 HTML 텍스트 영역 속성도 사용할 수 있음) |
mode: 'hybrid' |
입력할 때 실시간으로 서식(굵게, 기울임꼴, 제목)을 렌더링하는 WYSIWYG에서 영감을 받은 환경을 지원합니다. | |
도구 모음: 도구 모음에 표시되는 도구와 순서를 결정합니다. |
heading |
제목 수준 H1~H6을 선택하는 드롭다운을 엽니다. |
bold |
굵은 텍스트 형식을 활성화합니다. | |
italic |
기울임꼴 텍스트 서식을 활성화합니다. | |
strikethrough |
텍스트 취소선을 허용합니다. | |
ol |
(순서가 지정된 목록): 텍스트를 번호가 매겨진 목록 형식으로 변환합니다. | |
ul |
(순서가 없는 목록): 텍스트를 글머리 기호 목록으로 변환합니다. | |
checklist |
텍스트에 확인란을 추가하여 작업, 할 일 목록 또는 완료 상태 추적에 적합합니다. | |
blockquote |
인용되거나 강조된 텍스트를 강조표시합니다. | |
code |
인라인 코드에 대해 단일 백틱으로 선택한 텍스트를 래핑합니다. 다시 클릭하면 백틱이 제거됩니다. | |
codeblock |
삼중 백틱 울타리 코드 블록에서 선택한 텍스트를 래핑합니다. 다시 클릭하면 울타리가 제거됩니다. | |
hr |
해당 줄의 커서 위치에 --- 가로 눈금자를 삽입합니다. |
|
table |
커서 위치에 스타터 2x3 마크다운 테이블 템플릿을 삽입합니다. | |
image |
마크다운 구문을 통해 이미지를 삽입할 수 있습니다. | |
link |
텍스트에 하이퍼링크를 추가할 수 있습니다. | |
undo |
마지막 변경 사항을 되돌리려면 | |
redo |
마지막으로 실행 취소된 변경 사항을 다시 적용합니다. | |
indent |
들여쓰기 수준을 높이려면 | |
outdent |
들여쓰기 수준을 줄입니다. | |
preview |
전체 화면 병렬 미리보기를 전환합니다. 미리보기 창의 확인란을 클릭할 수 있으며 마크다운 소스를 즉시 업데이트할 수 있습니다. 전체 화면을 종료하려면 Esc를 누르세요. | |
| 고급 이미지 업로드 기능: 자신의 서버에 이미지 업로드를 구성하고 API를 통해 이미지 경로를 설정할 수 있습니다. 이렇게 하면 성능과 SEO가 향상됩니다. |
fileInput |
accept: 허용되는 이미지 파일 형식의 배열(예: 'webp', 'avif').uploadUrl: POST를 통해 파일이 전송되는 백엔드 엔드포인트.params: 추가 데이터(CSRF 토큰, 사용자 ID, 폴더 이름)를 위한 선택적 개체
|
altInput |
필수: 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)를 눌러 찾기 및amp; 교체 패널- 검색은 대소문자를 구분하지 않고 실시간 일치 카운터를 표시합니다(예: 12개 중 3개)
- ▲ / ▼ 버튼 또는
Enter/Shift + Enter를 사용하여 일치 항목을 탐색합니다. - 바꾸기는 현재 강조 표시된 일치 항목을 바꿉니다. 모두 바꾸기는 모든 항목을 한 번에 바꿉니다.
- 패널을 닫고 편집기로 포커스를 되돌리려면
Esc를 누르세요.
패널은 편집기 콘텐츠 영역의 오른쪽 상단에 떠 있으며 쓰기를 방해하지 않습니다.
🌙 테마
MarkdownEditor는 주변 페이지에서 테마를 자동으로 상속하므로 구성이 필요하지 않습니다. 편집기는 초기화 시 가장 가까운 상위 항목에서 data-theme를 읽으므로 기본적으로 사이트 테마와 동기화된 상태를 유지합니다.
테마 해결 방법(우선순위)
themeoption — 옵션 개체에 전달된 명시적 재정의<textarea>의data-theme— 요소에 직접 설정- 모든 조상의
데이터 테마— 예:<html>,<body>또는 래퍼<div>
사용 가능한 테마
'밝은'(기본값), '어두운', '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 - <textarea>에서 직접 data-theme를 설정합니다.
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 변수를 통한 맞춤 테마
.markdown-editor-wrapper 요소 또는 [data-theme] 선택기에서 CSS 변수를 재정의하여 편집기의 모양을 완전히 사용자 정의할 수 있습니다. 모든 색상은 지각적으로 균일한 결과를 위해 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' }); |
- 실시간 미리보기: 입력하는 즉시 렌더링된 마크다운을 확인하세요.
- 구문 강조: 명확한 코드와 마크다운 형식으로 가독성이 향상되었습니다.
- 쉬운 통합: 최소한의 설정으로 모든 웹 프로젝트에 원활하게 통합됩니다.
- 맞춤형 도구 모음: 굵게, 기울임꼴 등과 같은 도구 모음 옵션을 동적으로 구성하고 순서를 변경합니다.
특징
🔌 기본 양식 통합
표준 <textarea>와 정확히 동일하게 작동합니다. 복잡한 API가 없습니다. value 또는 name 속성만 사용하면 됩니다. PHP, Django 또는 Node.js의 표준 HTML 양식 제출과 함께 "작동"합니다.
🖼️ 고급 이미지 업로드
API를 통해 기본 서버 업로드를 구성합니다. 자체 CDN에서 이미지를 호스팅하여 더 빠른 페이지 로드와 우수한 SEO를 보장하려면 무거운 Base64 문자열을 피하세요.
🔀 하이브리드 및 일반 모드
시각적 편집을 위한 하이브리드(WYSIWYG) 환경과 전통적인 코딩 느낌을 위한 일반 마크다운 모드 간에 전환하세요.
🚀 고성능
"무거운 콘텐츠"에 최적화된 작은 ~116KB 번들입니다. 입력 지연이나 성능 저하 없이 대용량 문서 및 대용량 파일을 처리합니다.
🌍 내장 RTL 지원
아랍어, 우르두어, 페르시아어와 같은 오른쪽에서 왼쪽으로 쓰는 언어를 기본적으로 지원합니다. 전 세계적으로 액세스 가능한 애플리케이션을 구축하는 데 적합합니다.
🌙 적응형 테마
자동 다크 모드 지원이 포함됩니다. 원활한 시각적 경험을 위해 시스템 설정 또는 Frutjam UI 라이브러리와 동기화됩니다.
📝 스마트 편집
정렬된 목록, 정렬되지 않은 목록 및 체크리스트에 대한 GitHub 스타일 자동 목록 연속 — Enter를 누르면 편집기가 패턴을 계속합니다. 미리보기 창의 확인란을 클릭할 수 있으며 즉시 마크다운 소스에 다시 동기화됩니다.
📱 완전 반응형
이동 중에 편집할 수 있도록 데스크톱, 태블릿, 스마트폰에 완벽하게 적응하는 유연한 모바일 우선 UI입니다.
📦 범용 지원
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를 눌러 찾기 및amp; 바꾸다. 편집기를 종료하지 않고도 실시간 일치 카운터, 다음/이전 탐색, 단일 교체 및 모두 교체를 통해 대소문자를 구분하지 않는 검색이 가능합니다.
전체 구성 예
이 포괄적인 예를 사용하여 사용자 정의 도구 모음 순서 및 고급 이미지 업로드 처리를 포함한 모든 기본 기능으로 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'); }, 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(); |