js实现文本编辑器
实现基础文本编辑器
使用HTML的contenteditable属性创建一个可编辑区域,结合JavaScript实现基本功能:
<div id="editor" contenteditable="true"></div>
<button onclick="formatText('bold')">加粗</button>
<button onclick="formatText('italic')">斜体</button>
<script>
function formatText(command) {
document.execCommand(command, false, null);
}
</script>
使用document.execCommand
通过浏览器内置API实现常见编辑功能:
// 插入链接
document.execCommand('createLink', false, 'https://example.com');
// 修改字体大小
document.execCommand('fontSize', false, '5');
// 撤销/重做
document.execCommand('undo');
document.execCommand('redo');
使用现代API(Selection/Range)
对于更精细的控制,操作文本选区:
function insertTextAtCursor(text) {
const selection = window.getSelection();
const range = selection.getRangeAt(0);
range.deleteContents();
range.insertNode(document.createTextNode(text));
}
集成第三方库
推荐使用成熟的编辑器库:
-
Quill.js:

const quill = new Quill('#editor', { modules: { toolbar: true }, theme: 'snow' }); -
ProseMirror:
import { EditorState } from "prosemirror-state"; import { EditorView } from "prosemirror-view"; import { schema } from "prosemirror-schema-basic"; const view = new EditorView(document.querySelector("#editor"), { state: EditorState.create({ schema }) });
实现自定义工具栏
创建带有状态反馈的UI控件:
document.getElementById('bold-btn').addEventListener('click', () => {
const isActive = document.queryCommandState('bold');
document.execCommand('bold', false, null);
updateButtonState('bold-btn', !isActive);
});
function updateButtonState(btnId, active) {
const btn = document.getElementById(btnId);
btn.style.backgroundColor = active ? '#ddd' : '';
}
处理内容变化
监听编辑器内容变更:

const editor = document.getElementById('editor');
editor.addEventListener('input', () => {
console.log('Content changed:', editor.innerHTML);
});
// 对于第三方库
quill.on('text-change', (delta, oldDelta, source) => {
console.log('Content changed:', quill.getContents());
});
实现Markdown支持
将Markdown转换为HTML:
import marked from 'marked';
function renderMarkdown(content) {
editor.innerHTML = marked(content);
}
添加图片上传功能
处理文件选择和上传:
document.getElementById('upload-btn').addEventListener('change', (e) => {
const file = e.target.files[0];
const reader = new FileReader();
reader.onload = (event) => {
document.execCommand('insertImage', false, event.target.result);
};
reader.readAsDataURL(file);
});
实现版本历史
记录编辑历史:
let history = [];
let currentIndex = -1;
editor.addEventListener('input', () => {
const content = editor.innerHTML;
history = history.slice(0, currentIndex + 1);
history.push(content);
currentIndex = history.length - 1;
});
function undo() {
if (currentIndex > 0) {
currentIndex--;
editor.innerHTML = history[currentIndex];
}
}
响应式设计考虑
确保编辑器适应不同屏幕尺寸:
#editor {
min-height: 200px;
border: 1px solid #ddd;
padding: 10px;
resize: vertical;
overflow-y: auto;
}
@media (max-width: 600px) {
.toolbar { flex-wrap: wrap; }
.toolbar button { padding: 5px; }
}






