编辑器系列-初探quill


theme: smartblue

技术选型

最近需要做一个富文本编辑器的需求,目前star比较多的有quill,有34k star,以及slate,有25k star。

然后quill是纯原生的,可以不依赖任何框架,而slate的视图层需要结合slate-react,也就是要依赖react框架。

二者都易于扩展,方便自定义功能,也有丰富的api可供使用。

由于我们技术栈是vue,所以最后我们选择了quill来开发富文本编辑器。

入门

我们来看看怎么实现一个最简单的例子。

纯js,不依赖任何框架:

  <link href="https://cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet">
  <style>
    .container {
      margin: 20px auto;
    }
    #editor {
      height: 300px;
    }
  </style>
  <div class="container">
    <div id="editor"></div>
  </div>
  <script src="https://cdn.quilljs.com/1.3.6/quill.js"></script>
  <script>
    var quill = new Quill('#editor', {
      placeholder: '请在此输入',
      theme: 'snow'
    });
  </script>

image.png

上面我们使用的是,quill内置主题,snow。除了snow之外,还有bubble主题

bubble主题:

需要引入bublle的主题,并且把theme改成bubble

 <link href="https://cdn.quilljs.com/1.3.6/quill.bubble.css" rel="stylesheet">
 var quill = new Quill('#editor', {
  placeholder: '请在此输入',
  theme: 'bubble'
});

image.png

它跟snow主题不一样的是它的工具栏默认是隐藏的,工具栏需要选中词语后才会出现。

除了这两种主题外,quill还可以自定义主题,这个后面讲到模块再讲。

概念

quill内部是通过div的contenteditable属性实现可编辑的。

image.png

contenteditable属性里面,可以插入任意元素,这样感觉很不容易受控。

于是quill就定义了两个模型,一个数据模型,叫delta,一个dom模型,叫parchment

delta

delta数据模型,只有三种操作

  • insert 插入
  • delete 删除
  • retain 保留

这三种操作已经可以把大部分场景涵盖。

比如我想插入你好,我是答案cp3,并且加粗。用delta可以这样描述

// delta  加粗等属性可以使用attributes
[{ insert: "你好,我是答案cp3", attributes: { bold: true } }]

如果我想把答案二字删除,我们可以这样描述,先保留5个字符,再删除2个字符

// delta
[{retain: 5}, {delete: 2}]

image.png

有一个点需要注意⚠️:

插入和删除不能同时在一个delta,需要分开,不然删除不会有效果。

比如quill有api,可以设置设置初始内容和更新内容(setContentsupdateContents)。 它们接受的就是delta格式的数据。

    quill.setContents([
      { insert: "你好,我是答案cp3", attributes: { bold: true } },
      { retain: 5 },
      { delete: 2 }
    ])

不会删除答案二字。

正确的写法应该是:

    quill.setContents([
      { insert: "你好,我是答案cp3", attributes: { bold: true } }
    ])
    quill.updateContents([
      { retain: 5 },
      { delete: 2 }
    ])

parchment

quill转化delta数据格式,并不是直接转化成dom。

这里就要讲下parchment,它是dom模型,它模拟了html的dom tree结构。然后它是由各个类型的blot组成,比如inline blot,block blot,text blot,embed blot等。

quill转化delta数据格式,而是转成parchment的blot,由blot渲染成对应的dom。

我们可以在工具栏扩展我们的blot,然后当插入内容的时候,就能按照我们的定义的blot去渲染,达到自定义扩展的功能。

定义一个自定义blot:

    const Bold = Quill.import('formats/bold')
    class BoldRedColor extends Bold {
      static create () {
        const dom = super.create()
        dom.style.color = 'red'
        return dom
      }
    }
    Quill.register({ 'formats/bold': BoldRedColor }, true)

我们改写了工具栏的加粗功能,在加粗的时候同时给dom设置了红色的样式。

image.png

本文正在参加「金石计划 . 瓜分6万现金大奖」

© 版权声明
THE END
喜欢就支持一下吧
点赞8 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容