初探富文本之编辑器引擎

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了初探富文本之编辑器引擎相关的知识,希望对你有一定的参考价值。

初探富文本之编辑器引擎

在前文中我们介绍了富文本的基础概念,以及富文本的基本发展历程,那么在本文中将会介绍当前主流开源的富文本编辑器引擎。当前使用最广泛的富文本编辑器是​​L1​​​的富文本编辑器,其能满足绝大部份使用场景,由此也诞生了非常多优秀的开源富文本引擎,这其中有仅提供引擎的编辑器例如​​Slate.js​​​,也有提供了部分开箱即用的功能的例如​​Quill.js​​​,也有基于这些引擎二次开发的例如​​Plate.js​​​,本文主要介绍了​​Slate.js​​​、​​Quill.js​​​、​​Draft.js​​三款编辑器引擎。

Slate.js

​slate​​​是一个仅仅提供引擎的富文本​​core​​​,简单来说他本身并不提供各种富文本编辑功能,所有的富文本功能都需要自己来通过其提供的​​API​​​来实现,甚至他的插件机制也需要通过自己来拓展,所以使用​​slate​​​来构建富文本编辑器的话可定制度相当高。​​slate​​的文档虽然不是特别详细,但是他的示例是非常丰富的,在文档中也提供了一个演练作为上手的基础,对于新手还是比较友好的。话说回来如果只提供一个引擎的话,谁也不知道应该怎么用哈哈。

在​​slate​​的文档中有对于框架的设计原则上的描述:

  • 插件是一等公民,​​slate​​​最重要的部分就是插件是一等公民实体,这意味着你可以完全定制编辑体验,去建立像​​Medium​​​或是​​Dropbox​​这样复杂的编辑器,而不必对库的预设作斗争。
  • 精简的​​schema​​​核心,​​slate​​的核心逻辑对你编辑的数据结构进行的预设非常少,这意味着当你构建复杂用例时,不会被任何的预制内容所阻碍。
  • 嵌套文档模型,​​slate​​​文档所使用的模型是一个嵌套的,递归的树,就像​​DOM​​一样,这意味着对于高级用例来说,构建像表格或是嵌套引用这样复杂的组件是可能的,当然你也可以使用单一层次的结构来保持简单性。
  • 与​​DOM​​​相同,​​slate​​​的数据模型基于​​DOM​​​,文档是一个嵌套的树,其使用文本选区​​selections​​​和范围​​ranges​​​,并且公开所有的标准事件处理函数,这意味着像是表格或者是嵌套引用这样的高级特性是可能的,几乎所有你在​​DOM​​​中可以做到的事情,都可以在​​slate​​中做到。
  • 直观的指令,​​slate​​​文档执行命令​​commands​​来进行编辑,它被设计为高级并且非常直观地进行编辑和阅读,以便定制功能尽可能地具有表现力,这大大的提高了你理解代码的能力。
  • 可协作的数据模型,​​slate​​使用的数据模型特别是操作如何应用到文档上,被设计为允许协同编辑在最顶层,所以如果你决定要实现协同编辑,不必去考虑彻底重构。
  • 明确的核心划分,使用插件优先的结构和精简核心,使得核心和定制的边界非常清晰,这意味着核心的编辑体验不会被各种边缘情况所困扰。

示例

这样一段文本数据结构如下所示。

[

children: [
text: "这样" ,
text: "一段文本", italic: true ,
text: "的" ,
text: "数据结构", bold: true ,
text: "如下所示。" ,
],
,
];

优势

  • 可定制化程度非常高,几乎所有富文本表现层的功能都需要自行实现。
  • 非常轻量,本体只有一个内核,需要什么就做什么功能,体积可控。
  • 在设计架构时就针对协同提供了​​OP​​化的差量变更操作。
  • 数据结构是类似于​​DOM​​​的嵌套​​JSON​​结构,比较直观容易理解。

不足

  • 依旧处于​​Beta​​​阶段,可能会有重大​​API​​​变化,例如​​0.50​​版本就是全新重构的。
  • 虽然有协同的设计,但没有转换操作的​​OT​​​算法或​​CRDT​​算法的直接支持。
  • 仅有内核的架构同样也是不足,所有的功能都需要自行实现,成本比较高。
  • 新版​​slate​​​是无​​schema​​​的,这也就意味着​​Normalize​​需要自行实现。

参考

  • ​slate​​​官方文档​​https://docs.slatejs.org/​​。
  • ​slate​​​官方示例​​https://www.slatejs.org/examples/richtext​​。
  • 个人基于​​slate​​​实现的富文本编辑器​​https://github.com/WindrunnerMax/DocEditor​​。
  • 基于​​slate​​​的开箱即用富文本编辑器​​https://plate.udecode.io/docs/playground​​。
  • ​slate​​​的​​OT​​​协同实现参考​​https://github.com/solidoc/slate-ot​​。
  • ​slate​​​协同的​​OTTypes​​​参考​​https://github.com/pubuzhixing8/ottype-slate​​。
  • ​slate​​​的​​CRDT​​​协同实现参考​​https://github.com/humandx/slate-automerge​​。
  • ​slate​​​与​​YJS​​​协同结合的参考​​https://github.com/BitPhinix/slate-yjs​​。
  • 关于​​slate​​​非常不错的文章​​https://github.com/yoyoyohamapi/book-slate-editor-design​​。

Quill.js

​quill​​​是一个现代富文本编辑器,具备良好的兼容性及强大的可扩展性,还提供了部分开箱即用的功能。​​quill​​​是在​​2012​​​年开源的,​​quill​​​的出现给富文本编辑器带了很多新的东西,也是目前开源编辑器里面受众非常大的一款编辑器,至今为止的生态已经非常的丰富,可以在​​Github​​等找到大量的示例,包括比较完善的协同实例。

在​​quill​​的文档中有对于框架的设计原则上的描述:

  • ​API​​​驱动设计,​​quill​​​所有的功能都是通过​​API​​​来实现的并且可以直观的通过​​API​​​来获得数据的变化,以文本为中心的基础上构建的​​API​​​,不需要解析​html​​或者​​DIFF DOM​​​树,这样的设计可以让​​quill​​的功能更加的灵活与更高的可拓展性。
  • 自定义内容和格式,​​quill​​​公开了自己的文档模型,这是对​​DOM​​​的强大抽象,允许扩展和定制,由此数据结构的主角变成了​​Blots​​​、​​Parchment​​​、​​Delta​​。
  • 跨平台,​​quill​​有着比较良好的兼容性,在旧版本的浏览器中也可以相同的方式运行,在用户体验上不同浏览器中也可以有着相同的视图与交互效果,并且可以在桌面和移动设备上使用。
  • 易于使用,​​quill​​​携带了部分开箱即用的功能,如果不需要定制的话,这些功能已经足够了,同时​​quill​​又有着非常高的可拓展性,用来自定义各种功能。

示例

这样一段文本数据结构如下所示。


ops: [
insert: "这样" ,
insert: "一段文本", attributes: italic: true ,
insert: "的" ,
insert: "数据结构", attributes: bold: true ,
insert: "如下所示。\\\\n" ,
],
;

优势

  • ​API​​驱动设计,基础功能的支持很丰富,并且支持拓展。
  • 实现了视图层,实现上与框架无关,无论是​​Vue​​​还是​​React​​都可以轻松使用。
  • 使用了更加直观的​​Delta​​来描述数据结构,本身实现了操作转换的逻辑,可以非常方便地实现协同。
  • 生态非常丰富,有着非常多的插件与设计方案可以参考,特别是对于协同的支持可参考的地方非常多。

不足

  • ​Delta​​数据结构是扁平的,也就是一维的数据结构,这样在实现例如表格的功能时就比较麻烦。
  • ​quill 2.0​​​已经开发了很久了,但是还没有正式发布,目前的​​1.3.7​​版本已经有很多年没有更新了。
  • ​quill​​自带的功能很丰富,但这也就意味着其包的大小会比较大一些。

参考

  • ​quill​​​官方文档​​https://quilljs.com/docs/quickstart/​​。
  • ​quill​​​官方示例​​https://quilljs.com/standalone/full/​​。
  • ​quill​​​的​​Delta​​​设计与实现​​https://quilljs.com/docs/delta/​​。
  • ​quill​​​协同的​​OTTypes​​​参考​​https://github.com/ottypes/rich-text​​。
  • ​quill​​​的​​OT​​​协同实现参考​​https://github.com/share/sharedb/tree/master/examples/rich-text​​。
  • ​quill​​​的​​CRDT-yjs​​​的协同实现参考​​https://github.com/yjs/y-quill​​。

Draft.js

​draft​​​是用于在​​React​​​中构建富文本编辑器的框架,其为创建和自定义文本编辑器提供了强大的​​API​​​,并且旨在易于扩展和与其他库集成,与​​React​​​结合可以使开发者在进行编辑器开发时既不用操作​​DOM​​​、也不用单独学习一套构建​​UI​​​的范式,而是可以直接编写​​React​​​组件实现编辑器的​​UI​​​。​​draft​​​整体理念与​​React​​​非常的吻合,例如使用状态管理保存数据结构、使用​​immutable.js​​库、数据结构的修改基本全部代理了浏览器的默认行为、通过状态管理的方式修改富文本数据等。

在​​draft​​​的​​README​​中有对于框架的设计原则上的描述:

  • 可扩展和可定制,提供了构建块来创建各种丰富的文本组合体验,从基本文本样式到嵌入式媒体的支持。
  • 声明式富文本,​​draft​​​无缝融入​​React​​​,使用​​React​​​用户熟悉的声明式的​​API​​抽象出渲染、选择和输入行为的细节。
  • 不可变的编辑器状态,​​draft​​​模型是使用​​immutable.js​​​构建的,提供具有功能状态更新的​​API​​,并积极利用数据持久性来实现可扩展的内存使用。

示例

这样一段文本数据结构如下所示。


blocks: [

key: "3eesq",
text: "这样一段文本的数据结构如下所示。",
type: "unstyled",
depth: 0,
inlineStyleRanges: [
offset: 2, length: 4, style: "ITALIC" ,
offset: 7, length: 4, style: "BOLD" ,
],
entityRanges: [],
data: ,
,
],
entityMap: ,
;

优势

  • 具有灵活的​​API​​,可以轻松地扩展和自定义块和内联元素等。
  • 使用​​React​​​作为​​UI​​​层以及数据管理,可以充分利用​​React​​​生态,对​​React​​用户友好。
  • 没有过重大的​​Breaking Change​​,在稳定性与细节的处理上比较具有优势。

不足

  • 完全依赖于​​React​​​作为​​UI​​​层,与​​React​​​深度绑定,在其他​​UI​​框架上很难使用。
  • 数据结构模型的设计上不是很灵活,在实现表格等嵌套结构时比较受限。
  • ​draft​​针对性能进行了大量优化,但是在呈现大量内容时还是会感受到卡顿。

参考

  • ​draft​​​官方文档​​https://draftjs.org/docs/overview​​。
  • ​draft​​​官方示例​​https://draftjs.org/​​。
  • ​draft​​​的​​codesandbox​​​示例​​https://codesandbox.io/s/github/gupta-piyush19/Draft-JS-Editor​​。

每日一题

https://github.com/WindrunnerMax/EveryDay

参考

https://github.com/hzjswlgbsj/blog
https://zhuanlan.zhihu.com/p/425265438
https://jkrsp.com/slate-js-vs-draft-js/
https://www.zhihu.com/question/404836496
https://www.zhihu.com/question/449541344
https://github.com/cudr/slate-collaborative
https://blog.logrocket.com/what-is-slate-js-replace-quill-draft-js/
https://dev.to/charrondev/getting-to-know-quilljs---part-1-parchment-blots-and-lifecycle--3e76



以上是关于初探富文本之编辑器引擎的主要内容,如果未能解决你的问题,请参考以下文章

关于实现quill(富文本编辑器)初始化数据时自定义属性被清除的问题

富文本编辑器之游戏角色升级ing

django之百度Ueditor富文本编辑器后台集成

Django 之 富文本编辑器-tinymce

微信小程序实战之实现富文本编辑器

富文本使用之wangEditor3