js实现富文本编辑器
实现富文本编辑器的基本方法
使用JavaScript实现富文本编辑器通常基于contenteditable属性或现成的库。以下是两种主要方法:
基于contenteditable的简单实现
创建一个可编辑的div元素,通过document.execCommand执行格式化命令:
<div id="editor" contenteditable="true"></div>
<button onclick="formatText('bold')">加粗</button>
<button onclick="formatText('italic')">斜体</button>
<script>
function formatText(cmd) {
document.execCommand(cmd, false, null);
document.getElementById('editor').focus();
}
</script>
使用现有库(推荐) 主流库提供更完整的解决方案:
核心功能实现要点
选区与范围处理
通过window.getSelection()获取当前选区:
const selection = window.getSelection();
const range = selection.getRangeAt(0);
自定义命令封装 封装常见操作命令:
function insertHTML(html) {
const selection = window.getSelection();
if (selection.rangeCount) {
const range = selection.getRangeAt(0);
range.deleteContents();
const div = document.createElement('div');
div.innerHTML = html;
const frag = document.createDocumentFragment();
while (div.firstChild) {
frag.appendChild(div.firstChild);
}
range.insertNode(frag);
}
}
进阶功能实现
图片上传处理
使用FileReader实现本地图片预览:
document.getElementById('file-input').addEventListener('change', function(e) {
const file = e.target.files[0];
const reader = new FileReader();
reader.onload = function(event) {
insertHTML(`<img src="${event.target.result}">`);
};
reader.readAsDataURL(file);
});
撤销/重做功能 通过记录操作状态实现:
const history = [];
let historyIndex = -1;
function saveState() {
const html = editor.innerHTML;
history.length = historyIndex + 1;
history.push(html);
historyIndex++;
}
安全考虑
XSS防护 使用DOMPurify过滤HTML:
import DOMPurify from 'dompurify';
function safeInsert(html) {
const clean = DOMPurify.sanitize(html);
insertHTML(clean);
}
粘贴内容处理 拦截paste事件进行过滤:
editor.addEventListener('paste', function(e) {
e.preventDefault();
const text = (e.clipboardData || window.clipboardData).getData('text');
document.execCommand('insertText', false, text);
});
响应式设计建议
移动端适配 针对触摸设备优化:
if ('ontouchstart' in window) {
editor.style.minHeight = '300px';
editor.style.fontSize = '16px';
}
暗黑模式支持 通过CSS变量切换样式:

#editor.dark {
--bg-color: #222;
--text-color: #eee;
}
以上方法提供了从基础到进阶的实现方案,可根据项目需求选择适当的技术路径。使用现成库能快速获得生产级功能,而自定义实现则更适合特定场景需求。






