富文本总结(一):前置知识
Contents
编辑器技术阶段划分
Level 0
代表产品:UEditor、TinyMCE、CKEditor1-4
特点:
- 依赖了浏览器原生的
contenteditable
API 来实现编辑。 - 以
document.execCommand
API 为基础,封装一些语法糖进行内容操作。 - 视图即数据。
优点:
- 技术门槛低。
- 没有组合输入问题。
缺点:
- 兼容性差,相同操作在不同浏览器上会有不同实现,需要做各种兼容处理。
- 输出富文本内容是 HTML ,不利于管理数据。
- 扩展复杂的富文本很困难。
- 无法实现协同编辑。
Level 1
代表产品:Quill、Draft.js、Slate、ProseMirror
为了解决contentEditable
的不可靠,主流L1编辑器的做法是:
-
通过contenteditable依赖浏览器原生的编辑能力,通过事件监听、DOM 变更进行输入内容判断。
-
由编辑器提供的指令集,对内容进行操作。不再依赖
document.execCommand
。 -
视图和数据分离,由编辑器抽象的数据模型来描述视图层。
-
由编辑器控制内容解析,视图渲染解析后的DOM元素。
优点:
- 减少
document.execCommand
的一些不确定性问题。 - 可以支持多人协同。
缺点:
- 引入一些组合输入问题。例如中文输入法问题,不同浏览器的事件存在差异。
- 会有性能问题。
- 有些编辑器的数据模型是扁平化,不支持嵌套。扩展复杂的嵌套内容很困难。
编辑器 | 类型 | 数据方式 | 数据结构 | 特点 | 缺点 |
---|---|---|---|---|---|
Quill | 应用 | Delta | 线性结构 | ||
Prosemirror | 应用 | JSON+Schemas(范式) | 树形结构 | 新概念和 API 比较多,有着高昂的学习上手成本 | |
Draft.js | 框架 | 线性结构 | 基于React实现的组件,其他框架难以使用。 | ||
Slate | 框架 | JSON | 树结构 | 1. 视图层与内核分离,官方提供React视图层,可以基于内核实现Vue、Angular框架的渲染层。2. 插件作为一等公民,扩展性很好。 | 1. 底层重构多次,目前版本可能还不稳定。 |
数据结构扁平化,带来的好处就是没有层级,复杂度低,例如:
- 性能更好。
- 选区更容易计算。
- 节点的操作更容易,不需要考虑子节点
关于类型:
应用:提供了开箱即用的编辑器,集成了很多常用功能,例如变色,加粗,图片上传等,缺点是扩展性稍差。
框架:只提供基础的编辑功能,其他功能都需要自行实现。一般会通过插件的形式,扩展性较好。
Level 2
特点:
- 抛弃 contenteditable 、 document.execCommand 操作内容,全部改为自己实现。
- 脱离DOM,基于Canvas实现。
优点:
- 不存在兼容问题,可以保持一致性。
- 协同性
缺点:
- 开发量巨大,需要从0实现编辑器的所有功能,例如光标、选区、输入、渲染,a11y。
产品:Google Docs、飞书文档、腾讯文档等
contentEditable
浏览器所提供的<textarea />
和 <input />
都只允许用户输入「纯文本」,无法对内容中的文本加一些样式,例如变色,加粗。而HTML本身就是一个富文本,可以看下例子,
<div style="display: flex; height: 100vh; align-items: center; justify-content: center;">
<span style="color: blue;font-size: 20px;">bhwa233</span>
want
<span style="color: red;font-weight: bold;">fat</span>
</div>
而如果能在页面上编辑HTML就实现了富文本编辑器的能力,浏览器自身相应了响应的能力:
- 元素的 contentEditable 属性,允许节点内容被编辑。
- document.execCommand方法,允许对元素的操作,包括加粗、改背景、绑定链接、复制、剪切等。
但是存在兼容性问题,即不同浏览器对其编辑的行为实现不一致,导致在不同浏览器显示的效果出现很大差异。
详细:https://zhuanlan.zhihu.com/p/298101935
参考文章: