现代化富文本编辑器 Quill Editor
In 未分类 on 2017年09月20日 by view: 23,323
8

介绍

近期在弄富文本编辑器相关的内容,其中项目中使用了 Quill Editor(后面简称 Quill)。Quill 自称是一个现代化强大的富文本编辑器,它与其它富文本编辑器(例如 UEditor)不同的地方在于,过去的编辑器操作的数据和展现给用户的视图层是同一份 HTML/DOM,HTML 是树状结构,显然树状结构不如线性结构好处理,而 Quill 内部就是通过使用线性结构的方式使操作富文本编辑器变得简单,而且数据层和视图层是分离的,这让 Quill 对现在很流行的 React、Vue 或者 Angular 都能很好的支持。下面我简单介绍下 Quill 的使用:

简单的上手

简单的例子:

通过上面几行代码,我们就可以在浏览器里面看到一个简单的但又可以满足基本的富文本编辑器。

当然上面只是一个非常简单的文本编辑器,而 Quill 内置支持了很多富文本操作功能,它既提供了 UI 控制也提供了 API 操作。下面是一个完整的 Quill 自带的编辑器功能:

通过上图我们可以看到这些功能其实已经基本满足日常的富文本编辑需求了。

另外 Quill 提供了两套风格的主题以及常用的富文本编辑器模块:
1. 工具栏
2. 快捷键绑定
3. 历史记录
4. 剪贴板
5. 公式
6. 语法高亮

我们可以在初始化的时候对模块进行自定义的配置或者对模块进行扩展操作,具体文档可以查看:
Quill Modules

最后 Quill 也和其它文本编辑器一样提供了操作 api:
https://quilljs.com/docs/api/,通过 api 我们可以实现定制化的需求。

到这里我们还没看出 Quill 和其它富文本编辑器有什么区别,因为这才是刚刚开始,下面我会介绍 Quill 的独特功能。

Delta

前面说到 HTML 是树型结构,树型结构处理起来比较麻烦,而 Quill 通过变通引入了一个 Delta 的概念。
Delta 是用来描述富文本内容的一种简单的 JSON 格式。通过 Delta 我们就算不需要 DOM/HTML 也可以描述文本和格式化内容,甚至还可以描述文本内容变化。
而且 Delta 是线性结构的数据,因此操作更简便。
下面是一个使用 Delta 描述的富文本内容:

通过上面的描述,我们可以很清晰地知道有这么一段文本 “Gandalf the Grey”,其中 “Gandalf” 是加粗的,还有 “Grey” 的颜色值是 “#ccc”,最后一个 “\n” 就是代表换行,这里需要注意的是,如果换行这里也有 attributes,这在 Quill 里面表示的是当前行的格式,这里表示这段文字是被 h1 标签包裹的。

通过 Delta 来描述富文本内容,我们就可以摆脱使用 HTML 来描述富文本内容的困境,而且 Quill 还为 Delta 提供了非常丰富的 api 操作。
另外 Delta 还可以描述富文本内容变化,还是 “Gandalf the Grey” 这段文本作为例子:

学习 Delta 的概念很重要,因为如果我们需要增加一些定制化的功能,极有可能需要操作 Delta。
详细有关 Delta 的介绍可以参考官网这里
- https://quilljs.com/guides/designing-the-delta-format/
- https://quilljs.com/docs/delta/

blots & Parchment

Quill 里面有个 blots 的概念,想象一下,一段文字是一个段落,属于块状元素,该段落可以包含以下几种基础元素:
- 块状元素 (Block),例如标题;块状样式,例如行高,缩进,居中等;
- 纯文本内容 (Text),是个叶子结点;
- 内联元素 (Inline),例如等;内联样式,例如文字颜色,文字大小等;
- 非文本叶子结点 (Embed),例如图片,视频;

而 blots 就是由这些类型组合,实际上在 Quill 里面这些分类统称为 Parchment,
Parchment 主要作用就是操作文档模型,我们可以通过其提供的接口进行 DOM 初始化,返回指定格式或者指定标签和作用域等等。Quill 里面的 blots 都是通过继承 Parchment 里面的类来进行扩展。
举个例子,例如我想实现一个添加链接和加粗功能,这个时候就可以用到 Parchment:

上面的代码实现的是,我想点击指定的按钮给富文本应用加粗和添加链接功能。

熟练使用 Parchment 对我们日后如果需要新增 Quill 没有的功能或者个性化的功能非常有用(同时也是必须)。Parchment 这一块如果要深入讲解需要不少篇幅,下一篇文章我会单独讲解 Parchment 的使用。
Parchment 有关的资料:
- https://quilljs.com/guides/cloning-medium-with-parchment/
- https://github.com/quilljs/parchment

总结

Quill 的一个缺点就是文档比较少的,而且都是英文文档。如果我们只是需要基本功能,我们可以不用了解 api,Delta 和 Parchment 的概念,只需要简单引入 js 然后初始化就可以了。但如果设涉及到个性化的功能时,我们就必须了解和熟悉这些概念,而且必须查看 Quill 的源码,好在 Quill 的源码实现还是比较优雅的。
Quill 使用了和其它富文本编辑器不一样的理念来表达和处理富文本,让我们摆脱了 HTML 和 DOM 带来的烦恼,使一切都变得简化.
当然 Quill 也会有坑,毕竟整个富文本编辑就是一个大坑。我目前遇到的几个问题就是:
1. Quill 用到了 MutationObserver,这表示对一些老式的浏览器会不支持。
2. Quill 的 Range 和 Selection 底层用的原生的 api,我们也知道原生的 Selection/Range 本来就比较坑,不然就不会有人自己实现一套 Selection 和 Range 了。
3. 刚刚说的,就是文档太少了,Modules 的配置项和 Parchment 的使用,很难找到深入了解的文章,只能自己去看源码。
总的来说 Quill 还是给我们带来了很多好处,相信未来 Quill 一定会越来越好。

原创文章转载请注明:

转载自AlloyTeam:http://www.alloyteam.com/2017/09/13191/

  1. 1231 2018 年 1 月 22 日

    🙂 🙂 不错

  2. king 2017 年 12 月 25 日

    有没遇到 quill 本地用是好的,angular4 打包发布后就有问题了

  3. jakey 2017 年 10 月 26 日

    关键还是看性能,我的编辑器有时几千条的代码就会卡顿,甚至数据丢失。
    这个感觉不错,正好需要替换现有的编辑器。
    从文本,到 textarea 再到编辑器,一步步改进。

  4. yantze 2017 年 10 月 4 日

    其实是 text model 与 html 响应式的实现。最早可能是 Etherpad 开始使用,后来石墨文档用的也是这种方式。

    感觉这种挺好的,可扩展性极强,二次开发再扩展最省时间。 🙂

  5. Nicholas 2017 年 9 月 26 日

    您好,想请教一个问题——微信公众号的第三方编辑器(例如:秀米、135、i 排版)等,弄好的模板,直接复制,然后在微信公众号的编辑器上粘贴,全部格式都保留了下来,而且几乎是无缝对接。

    而我试了一下,将秀米的模板粘贴到 wangEditor、UEditor、还有本文推荐的 Quill ,都不是无缝对接的,格式还是不能完全保留下来。

    听说微信用的也是 UEditor,不过他们自己修改过,想请问一下实现上述功能(第三方编辑器复制模板,粘贴到富文本上并且保留格式)的原理是什么?

    • 嘻嘻 2017 年 11 月 2 日

      微信的第三方编辑器无缝粘贴,我的理解:直接把 html(带行内样式)给插入到微信公众号的编辑器里了。而别的编辑器(比如 wangEditor 等)对于粘贴进来的内容都进行了一道过滤,有些样式就给过滤没了

  6. 阿伟 2017 年 9 月 22 日

    这个对中文支持友好么

    • pauli 2018 年 2 月 23 日

      中文支持挺好的,我用的是 utf-8 字符,从来没有出现过乱码。自己写的扩展也挺正常

发表评论