js 实现富文本编辑器
实现富文本编辑器的方法
使用 contenteditable 属性
HTML5 的 contenteditable 属性可以让任何 DOM 元素变成可编辑状态。这是实现富文本编辑器的基础。
<div id="editor" contenteditable="true"></div>
通过 JavaScript 可以监听用户输入并添加样式:
document.getElementById('editor').addEventListener('input', function() {
// 处理输入内容
});
使用 document.execCommand
这是传统的富文本编辑 API,可以直接执行格式化命令:
// 加粗选中文本
document.execCommand('bold', false, null);
// 插入链接
document.execCommand('createLink', false, 'https://example.com');
虽然简单易用,但该 API 已被标记为废弃,现代项目建议使用更先进的方案。
使用现代库
目前主流的富文本编辑器库包括:
-
Quill:模块化设计,支持自定义格式和扩展
const quill = new Quill('#editor', { theme: 'snow', modules: { toolbar: [ [{ header: [1, 2, false] }], ['bold', 'italic', 'underline'], ['image', 'code-block'] ] } }); -
TinyMCE:功能全面,商业项目常用
tinymce.init({ selector: '#editor', plugins: 'advlist link image lists', toolbar: 'undo redo | styleselect | bold italic' }); -
ProseMirror:更适合需要深度定制的场景
import { EditorState } from "prosemirror-state"; import { EditorView } from "prosemirror-view"; import { schema } from "prosemirror-schema-basic";
let state = EditorState.create({ schema }); let view = new EditorView(document.querySelector("#editor"), { state });
#### 自定义实现
对于需要完全控制的情况,可以基于 Selection 和 Range API 自行实现:
```javascript
function applyStyle(style) {
const selection = window.getSelection();
if (selection.rangeCount > 0) {
const range = selection.getRangeAt(0);
const span = document.createElement('span');
span.style[style.property] = style.value;
range.surroundContents(span);
}
}
处理内容安全
富文本编辑器需要特别注意 XSS 防护:
function sanitize(html) {
const temp = document.createElement('div');
temp.textContent = html;
return temp.innerHTML;
}
或者使用专门的库如 DOMPurify:
const clean = DOMPurify.sanitize(dirtyHTML);
实现撤销/重做
使用命令模式记录操作历史:
class History {
constructor() {
this.stack = [];
this.index = -1;
}
push(state) {
this.stack.length = this.index + 1;
this.stack.push(state);
this.index++;
}
undo() {
if (this.index > 0) {
this.index--;
return this.stack[this.index];
}
}
redo() {
if (this.index < this.stack.length - 1) {
this.index++;
return this.stack[this.index];
}
}
}
注意事项
- 移动端需要特别处理触摸事件和虚拟键盘
- 不同浏览器对 contenteditable 的实现有差异
- 复杂格式(如表格、嵌套列表)需要额外处理
- 考虑添加 Markdown 兼容模式提升用户体验
现代富文本编辑器实现通常结合多种技术,建议根据项目需求选择合适的方案或现有库。







