Fragmenta CMS富文本编辑器揭秘:contenteditable工具栏如何清洗脏HTML
【免费下载链接】fragmenta-cmsA user-friendly CMS written in Go (golang)项目地址: https://gitcode.com/gh_mirrors/fr/fragmenta-cms
Fragmenta CMS 是一款用 Go 语言编写的开源内容管理系统,它的富文本编辑器不依赖任何第三方库,仅凭原生contenteditable加一段轻量脚本,就实现了所见即所得编辑与 HTML 清洗能力。本文带你揭秘:它的 contenteditable 工具栏是如何工作,又是如何在输入、点击、提交三个时机层层"拦截",把从 Word 粘贴进来的脏 HTML 变得干净整洁的 🧹
为什么富文本编辑器的 HTML 需要清洗?
用contenteditable做富文本编辑器,最大的坑不是"写不出来",而是"存不干净":
- 从 Word / TextEdit 粘贴进来一大坨
style内联样式、<font color>标签 - 微软专属"垃圾":
MsoNormal类名、<o:p>空段落、HTML 注释 - 浏览器自动生成的空
<span>,以及justify命令产生的内联text-align
Fragmenta CMS 的答案很朴素:不引入重型编辑器库,而是把清洗逻辑拆成三道防线,覆盖内容进入编辑区的每个关键时机(核心实现见src/lib/editable/assets/scripts/editable.js)。
contenteditable 工具栏的工作原理:三件套架构
编辑区由三个元素组成,藏在一个普通<form>里(用法示例见src/lib/editable/views/example.html.got):
| 元素 | 类名/标识 | 作用 |
|---|---|---|
| 工具栏 | .content-editable-toolbar | 一排按钮,点击触发document.execCommand |
| 隐藏 textarea | .content-textarea | 真正随表单提交的字段,平时隐藏 |
| 可视化编辑区 | .content-editable(带contenteditable属性) | 用户实际打字的地方,默认展示 |
💡 关键点:用户看到的是contenteditable区块,但表单提交的始终是 textarea。脚本在表单submit时把编辑区的 HTML 同步进 textarea,两个世界各取所需。
三档可选的工具栏模板
| 模板文件 | 包含按钮 |
|---|---|
editable-toolbar-basic.html.got | 段落、加粗、斜体、链接、查看源码 |
editable-toolbar.html.got(默认) | 上述 + H1~H5 标题、有序/无序列表、左/右/居中、引用 |
editable-toolbar-full.html.got | 默认全部 + 代码块(pre) |
按钮的id直接就是execCommand命令名:Bold、Italic、insertorderedlist、justifyCenter……标题和引用则复用formatblock命令,用data-format属性区分h1~h5、p、blockquote。点击"查看源码"(showCode)按钮时,编辑区切换成深色等宽字体的 HTML 源码视图,改完再切回来——这也是为什么编辑器内置了一个"暗色代码面板"。
页面(src/pages/views/form.html.got)和文章(src/posts/views/form.html.got)的编辑表单都通过模板指令{{ template "lib/editable/views/editable-toolbar.html.got" }}一行引入工具栏,接入成本极低。
三道清洗防线:脏 HTML 无处遁形 🔍
第一道:输入时的实时清理
每次编辑区发生input事件,立即执行cleanHTMLElements:
- 遍历
p, div, b, i, h1~h6,移除全部style属性("不允许内联样式"是铁律) span额外移除style和langfont标签移除color属性
第二道:点击工具栏后的定向清理
execCommand执行完不是完事,脚本会取选区的公共祖先元素getSelectionParentElement(),再做两件事:
cleanAlign:把justifyLeft/Center/Right产生的内联text-align样式,转写成align-left / align-center / align-right三个 CSS 类(配合!important,见src/lib/editable/assets/styles/editable.css),同时移除残留style属性cleanHTMLElements:对选区再次扫一遍样式垃圾
第三道:提交前的正则深度清洗
点击"查看源码"或表单提交时,updateContent会把编辑区 HTML 交给cleanHTML处理,一组正则依次出动:
| 正则目标 | 清洗效果 |
|---|---|
<span>空标签 | 整对移除 |
<font ...>标签 | 全部移除(第一道防线漏网的) |
| 还原为普通空格 |
<p></p>空段落 | 转为换行符,保持排版美观 |
<!-- -->注释、MsoNormal、<o:p> | 微软 Office 专属垃圾,统统删除 |
连续排列的ul/ol/li/p/h* | 自动插入换行,源码更易读 |
三道防线层层递进:输入拦样式 → 点击拦对齐垃圾 → 提交前正则兜底,最终存进数据库的 HTML 简短、无内联样式、无厂商私有标记。
如何快速接入这套编辑器?
在自己的页面表单里放齐"三件套"即可(按钮模板 + 隐藏 textarea +content-editable区块),脚本启动时自动扫描.content-editable-toolbar完成绑定,无需手写初始化代码:
- 引入工具栏模板(三档任选,见
src/lib/editable/views/目录) - 放置
<textarea class="content-textarea">与<div contenteditable class="content-editable"> - 加载
src/lib/editable/assets/scripts/editable.js与src/lib/editable/assets/styles/editable.css
想自己动手试试?克隆仓库后阅读src/lib/editable/即可:
git clone https://gitcode.com/gh_mirrors/fr/fragmenta-cms关键文件速查 📁
| 文件 | 说明 |
|---|---|
src/lib/editable/assets/scripts/editable.js | 工具栏激活 + 三套清洗函数核心逻辑 |
src/lib/editable/views/editable-toolbar.html.got | 默认工具栏模板 |
src/lib/editable/views/editable-toolbar-basic.html.got | 精简版工具栏模板 |
src/lib/editable/views/editable-toolbar-full.html.got | 完整版工具栏模板(含代码块) |
src/lib/editable/assets/styles/editable.css | 工具栏按钮、编辑区与对齐类的样式 |
src/pages/views/form.html.got/src/posts/views/form.html.got | 编辑器在页面与文章表单中的实际应用 |
总结:Fragmenta CMS 的富文本编辑器证明了——contenteditable+execCommand+ 针对性清洗函数,就足以撑起一个干净可靠的 CMS 编辑器。没有庞大依赖,只有对"脏 HTML"的精确打击,这正是它值得新手研究的原因。
【免费下载链接】fragmenta-cmsA user-friendly CMS written in Go (golang)项目地址: https://gitcode.com/gh_mirrors/fr/fragmenta-cms
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考