核心是contenteditable="true"配合execCommand实现轻量编辑:需加tabindex="0"确保聚焦,监听paste清理粘贴内容,用innerHTML保存带格式内容、textContent提取纯文本,回车默认插<div>可拦截改为<p><br></p>。
用 contenteditable 实现轻量级富文本编辑,核心是“原生属性 + 原生 API”,不依赖任何库。它不是模拟输入,而是让元素真正参与焦点、光标、剪贴板交互,所以加粗、换行、粘贴等行为天然可用。
只写 <div contenteditable="true"></div> 是不够的。常见问题:键盘无法聚焦、回车插入 <div> 而非段落。
tabindex="0",否则 tab 键和 JS .focus() 失效min-height 和边框(如 border: 1px solid #ddd),避免空内容时不可见<div>,若需语义化段落,可监听 keydown 拦截 Enter 并手动插入 <p><br></p>
document.execCommand() 虽已废弃,但目前所有主流浏览器仍完整支持,且对简单场景足够稳定、代码极简。
<button data-command="bold">B</button>
document.execCommand(cmd, false, value),其中 value 用于颜色、链接、图片等传参"bold"、"italic"、"underline"、"insertUnorderedList"、"justifyCenter"、"foreColor"、"createLink"、"insertImage"
editor.focus(),确保光标留在编辑区用户粘贴 Word 或网页内容时,常带冗余样式、嵌套标签甚至脚本,直接存入会引发 XSS 风险或渲染错乱。
paste 事件,e.preventDefault() 阻止默认行为e.clipboardData.getData('text/plain') 获取纯文本,再用 execCommand('insertText', false, text) 插入DOMPurify.sanitize(html, {ALLOWED_TAGS: ['b','i','u','p','br']}) 过滤后再插入<br> 的空段落,避免编辑区塌陷失焦用户编辑后的内容,不能无脑取 innerHTML 就发给后端——它可能含不可信 HTML;也不能只取 textContent——会丢失所有格式。
innerHTML(但必须服务端或前端二次过滤)textContent
style 属性、class(除非你主动管理)、data- 属性;保留 <b>、<i>、<p>、<ul> 等语义标签input 或 blur 事件触发保存,避免高频触发影响性能