最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 通过 Quill API 实现对编辑器内容的完全控制(附有查找替换功能的实现)

    正文概述 掘金(DevUI团队)   2021-07-08   548

    DevUI 是一款面向企业中后台产品的开源前端解决方案,它倡导沉浸灵活至简的设计价值观,提倡设计者为真实的需求服务,为多数人的设计,拒绝哗众取宠、取悦眼球的设计。如果你正在开发 ToB工具类产品,DevUI 将是一个很不错的选择!

    通过 Quill API 实现对编辑器内容的完全控制(附有查找替换功能的实现)

    以下文章和本文相关,也许你也会喜欢:

    《现代富文本编辑器Quill的模块化机制》

    《Quill富文本编辑器的实践》

    《如何将龙插入到编辑器中?》

    《今天是儿童节,整个贪吃蛇到编辑器里玩儿吧》

    《现代富文本编辑器Quill的内容渲染机制》

    《Quill基本使用和配置》

    引言

    这是深入浅出 Quill 系列的第2篇。

    上一篇我们介绍了 Quill 的基本使用和配置,相信大家能够使用 Quill 搭建一个简单的富文本编辑器啦。

    不过实际的业务场景可能更复杂,有更多定制的需求,Quill 能否满足呢?

    Quill 是一款 API 驱动的富文本编辑器,它的内容可以通过API实现完全的掌控,我们一起来看看吧。

    1 对内容的控制

    富文本编辑器最基本的操作就是对内容的///,比如:

    • 在编辑器某处增加一些文本
    • 选中编辑器中的一部分内容,将其删除
    • 选中一部分文本,给它添加某种格式
    • 获取其中一部分内容,对其进行转换

    以上操作直接通过键盘和鼠标很容易操作,但是通过 API 如何实现呢?

    1.1 删

    先看的部分,通过deleteText()方法实现,该方法主要有两个入参:

    • index 从哪儿删除
    • length 删除多少内容

    比如我想把下面的Hello 删除:

    this.quill.deleteText(0, 6);
    

    通过 Quill API 实现对编辑器内容的完全控制(附有查找替换功能的实现)

    又比如我想删除编辑器里的所有内容,但我们不知道里面一共有多少内容,是不是需要一个一个数一下呢?

    其实是不需要的,Quill 提供了一个查询编辑器总字符数的方法getLength()(后面介绍的部分也会讲到)。

    所以删除所有内容也很简单:

    this.quill.deleteText(0, this.quill.getLength());
    

    还有一种常见的情况,就是我们想删除编辑器中选中的内容,这要如何实现呢?

    Quill 提供了一个获取编辑器选区的方法getSelection()(后面介绍对选区的控制时会讲到)可以轻松实现:

    // 获取选区内容所在的index和length
    const { index, length } = this.quill.getSelection();
    
    this.quill.deleteText(index, length);
    

    通过 Quill API 实现对编辑器内容的完全控制(附有查找替换功能的实现)

    是不是非常方便呢?

    1.2 查

    再来看的部分,Quill 托管了编辑器里所有的内容,因此它对里面的内容了如指掌,Quill 知道:

    • 指定位置有什么内容
    • 有多少内容
    • 它的格式是什么

    可以使用getText()方法获取纯文本内容,它的使用方式和前面介绍过的deleteText()类似:

    // 获取指定位置的文本
    this.quill.getText(0, 6);
    
    // 不传入任何参数,可以获取全部文本
    this.quill.getText();
    
    // 获取选中文本
    const { index, length } = this.quill.getSelection();
    this.quill.getText(index, length);
    

    都知道有什么内容了,拿到内容的长度就很简单了:

    const length = this.quill.getText().length;
    

    Quill 提供了一个简便的方法getLength(),可以直接拿到全部文本的长度:

    const length = this.quill.getLength();
    

    要获取选中文本的长度,可以使用之前介绍过的getSelection()方法:

    const length = this.quill.getSelection().length;
    

    1.3 增

    1.3.1 插入文本

    往编辑器里增加格式化的内容是最常见的需求,Quill 针对该场景提供了非常丰富的 API,最基础的就是insertText()方法。

    该方法既可以增加纯文本,又可以增加带格式的文本。

    插入纯文本需要传入两个参数:

    • index 从哪个位置插入文本
    • text 插入什么文本
    this.quill.insertText(0, 'DevUI 是一款面向企业中后台产品的开源前端解决方案');
    

    插入带格式的文本需要额外传入两个参数:

    • format 格式的名字
    • value 格式的值

    比如我想在当前光标后面插入一个带超链接的DevUI

    const range = this.quill.getSelection();
    if (range) {
      this.quill.insertText(range.index, 'DevUI', 'link', 'https://devui.design/');
    }
    

    通过 Quill API 实现对编辑器内容的完全控制(附有查找替换功能的实现)

    1.3.2 插入嵌入内容

    插入嵌入内容的方法insertEmbed(),相信大家都很熟悉了,我在之前的

    • 《Quill富文本编辑器的实践》
    • 《如何将龙插入到编辑器中?》
    • 《今天是儿童节,整个贪吃蛇到编辑器里玩儿吧》

    三篇文章中多次使用过这个API。

    这个方法和insertText()的区别在于没有第二个参数,因为它不需要插入文本。

    比如插入B站风格的分割线:

    const index = this.quill.getSelection().index;
    this.quill.insertEmbed(index, 'divider', {
      url: 'assets/images/divider.png',
      width: '660px',
    });
    

    通过 Quill API 实现对编辑器内容的完全控制(附有查找替换功能的实现)

    比如插入龙:

    const index = this.quill.getSelection().index;
    this.quill.insertEmbed(index, 'dragon', {
      id: 'canvas-dragon',
    });
    

    通过 Quill API 实现对编辑器内容的完全控制(附有查找替换功能的实现)

    比如插入贪吃蛇小游戏

    const index = this.quill.getSelection().index;
    this.quill.insertEmbed(index, 'snake', {
      id: 'canvas-snake',
    });
    

    通过 Quill API 实现对编辑器内容的完全控制(附有查找替换功能的实现)

    1.3.3 用纯文本替换现有内容

    这两个方法都是在现有内容的基础上新增文本。

    如果要直接用新的内容替换现有文本,要怎么做呢?

    使用以下两个set方法即可:

    • setText 设置纯文本
    • setContents 设置带格式的文本

    setText()方法只有一个参数:

    • text 需要插入的纯文本
    this.quill.setText('Hello DevUI!');
    

    如果text参数传入空字符串,则会清空编辑器内容:

    this.quill.setText('');
    

    1.3.4 用 delta 数据替换现有内容

    setContents()方法非常强大,可以使用指定的 delta 数据来渲染编辑器的内容。

    比如我们想要将当前富文本的内容变成一个贪吃蛇游戏:

    this.quill.setContents([
      { insert: { snake: { id: 'snake' } } }
    ]);
    

    一般 delta 数据会存储在数据库中,使用 delta 来初始化编辑器内容时,可以使用该方法。

    1.4 改

    setContents()方法还有一个兄弟叫updateContents(),这俩兄弟本领都非常强。

    updateContents()方法可以使用 delta 更新编辑器中的指定内容。

    比如我想把选中的Quill内容变成DevUI,并加上超链接,不使用updateContents()方法的情况下,我们需要调用多个方法:

    const { index, length } = this.quill.getSelection();
    this.quill.deleteText(index, length);
    this.quill.insertText(index, 'DevUI', 'link', 'https://devui.design/');
    

    我们再来看看使用updateContents()方法如何实现:

    this.quill.updateContents([
      { retain: index },
      { delete: length },
      { insert: 'DevUI', attributes: { link: 'https://devui.design/' } }
    ]);
    

    两种方法的效果一样,但是后者只需要调用一个方法。

    2 对格式的控制

    2.1 删

    除了可以删除编辑器内容外,我们可能还需要清除某部分内容的格式,清除格式可以使用removeFormat()方法,该方法的使用方式和deleteText()几乎是一样的,不再赘述。

    // 清除指定位置和长度的文本的格式
    this.quill.removeFormat(0, 6);
    
    // 清除全部文本的格式
    this.quill.removeFormat(0, this.quill.getLength());
    
    // 清除选中文本的格式
    const { index, length } = this.quill.getSelection();
    this.quill.removeFormat(index, length);
    

    2.2 查

    获取单一格式

    getText()方法只能拿到纯文本,并不知道里面有什么格式,要想获取指定文本的格式,可以使用getFormat()方法,使用方式都一样。

    // 获取选中文本的格式
    const { index, length } = this.quill.getSelection();
    const format = this.quill.getFormat(index, length);
    

    比如粗体的格式:

    { bold: true }
    

    超链接的格式:

    { link: "https://juejin.cn/post/6976023288753586184" }
    

    通过 Quill API 实现对编辑器内容的完全控制(附有查找替换功能的实现)

    获取 Delta 格式

    不过getFormat()方法只能拿到单一的格式,如果想知道指定内容的全部格式信息,需要使用一个更加强大的API:getContents(),这个方法能获取内容的 delta 形式,而 delta 格式不仅描述了有什么内容,还描述了这些内容的格式是什么。

    比如以下选中的内容,我们看看它的内容和格式是什么。

    通过 Quill API 实现对编辑器内容的完全控制(附有查找替换功能的实现)

    调用getContents()方法:

    const { index, length } = this.quill.getSelection();
    const contents = this.quill.getContents(index, length);
    console.log('contents:', contents);
    

    打印了以下信息:

    {
      ops: [
        { insert: '删除内容' },
        { attributes: { header: 2 }, insert: '\n' }, // 标题二格式
        { insert: '先看' },
        { attributes: { code: true }, insert: '删' }, // 行内代码格式
        { insert: '的部分,通过' },
        { attributes: { code: true }, insert: 'deleteText()' }, // 行内代码格式
        { insert: '方法实现,该方法主要有两个入参:\nindex 从哪儿删除' },
        { attributes: { list: 'bullet' }, insert: '\n' }, // 无序列表格式
        { insert: 'length 删除多少内容' },
        { attributes: { list: 'bullet' }, insert: '\n' }, // 无序列表格式
        { insert: '比如我想把下面的' },
        { attributes: { code: true }, insert: 'Hello ' }, // 行内代码格式
        { insert: '删除:\nthis.quill.deleteText(0, 6);' },
        { attributes: { 'code-block': true }, insert: '\n' }, // 代码块格式
        { insert: '\n' }
      ]
    }
    

    从以上 delta 结构我们很容易得出编辑器内容的格式信息:

    • 删除内容是标题二格式
    • /deleteText()/Hello 是行内代码格式
    • index 从哪儿删除length 删除多少内容是无序列表格式
    • this.quill.deleteText(0, 6);是代码块格式
    • 其他内容都是纯文本格式

    是不是一目了然呢?

    2.3 增

    除了删除和查找格式之外,还可以设置格式,Quill提供了3个设置格式的方法:

    • format(format, value) 设置选中文本的格式
    • formatLine(index, length, format, value) 设置行(块级)格式
    • formatText(index, length, format, value) 设置指定位置的文本格式
    // 设置选中文本为粉色
    this.quill.format('color', 'pink');
    
    // 设置第10-20个字符为粉色
    this.quill.formatText(10, 10, 'color', 'pink');
    
    // 设置第一行为有序列表
    this.quill.formatLine(0, 1, 'list', 'ordered');
    

    3 对选区的控制

    3.1 查

    3.1.1 查询选区信息

    获取当前选区或光标的方法getSelection(),我们在前面已经使用过多次,说明这个方法是一个非常实用的高频方法。

    该方法不需要传入参数,返回当前选区信息:

    • index 选区开始位置
    • length 选区长度
    {
      index: 0,
      length: 3
    }
    

    如果只有光标,没有选择任何内容,则返回的length0

    如果编辑器没有光标,则返回null

    3.1.2 查询文本相对定位位置

    除了查询选区位置和长度,还可以使用getBounds()方法查询指定位置的文本在编辑器容器中的相对定位位置,该方法有两个入参:

    • index 选区开始位置
    • length 选区长度

    比如我想看下编辑器开头的三个字符的位置:

    const bounds = this.quill.getBounds(0, 3);
    

    返回结果:

    {
      bottom: 49.100006103515625
      height: 22.5
      left: 18
      right: 66
      top: 26.600006103515625
      width: 48
    }
    

    3.2 增

    除了查看当前选区信息,我们还可以使用setSelection()方法手动设置选区和光标位置,该方法有两个参数:

    • index 选区开始位置
    • length 选区长度

    如果只设置第一个参数,将只设置光标位置,不选中文本:

    // 将光标定位到第10个字符后面
    this.quill.setSelection(10);
    

    两个参数同时设置将选中文本:

    // 选中第1到10个字符
    this.quill.setSelection(0, 10);
    

    选区和光标是后续操作的基础,所以该方法和getSelection()方法一样,是一个非常常用的方法。

    4 小结

    我们做一个简单的小结:

    • 对内容的控制
      • 删除内容 deleteText(index, length)
      • 查找内容 getText(index, length)
      • 获取编辑器内容长度 getLength()
      • 插入文本内容 insertText(index, text, format, value)
      • 插入嵌入内容 insertEmbed(index, format, value)
      • 使用纯文本替换内容 setText(text)
      • 用 delta 数据替换现有内容 setContents(delta)
      • 用 delta 更新内容 updateContents(delta)
    • 对格式的控制
      • 删除格式 removeFormat(index, length)
      • 查找单一格式 getFormat(index, length)
      • 获取 Delta 格式 getContents(index, length)
      • 设置选中文本的格式 format(format, value)
      • 设置行格式 formatLine(index, length, format, value)
      • 设置文本格式 formatText(index, length, format, value)
    • 对选区的控制
      • 获取选区/光标信息 getSelection()
      • 获取指定文本的相对定位 getBounds(index, range)
      • 设置选区/光标 setSelection(index, range)

    5 案例:查找替换功能

    最后我们用一个查找替换的案例来温故下之前介绍过的 API。

    // 待查找文本
    const str = 'Quill';
    const length = str.length;
    
    // 匹配目标文本的正则
    const reg = new RegExp(str, 'g');
    
    let match;
    while ((match = reg.exec(this.quill.getText())) !== null) {
      // 目标文本在文档中的位置
      const index = match.index;
      
      // 匹配到目标文本之后,我们可以对该文本做高亮或替换的处理
      
      // 高亮
      this.quill.formatText(index, length, 'background', '#ef0fff');
      
      // 替换
      this.quill.deleteText(index, length);
      this.quill.insertText(index, 'DevUI', 'link', 'https://devui.design/');
    }
    

    查找替换动画演示效果:

    通过 Quill API 实现对编辑器内容的完全控制(附有查找替换功能的实现)

    小结

    本文主要介绍了 Quill 的常用API,以及每个API的使用场景。

    后续将介绍更多关于 Quill 的实践,关注 DevUI 不迷路?。

    欢迎加DevUI小助手微信:devui-official,一起讨论Angular技术和前端技术。

    欢迎关注我们DevUI组件库,点亮我们的小星星?:

    github.com/devcloudfe/…

    也欢迎使用DevUI新发布的DevUI Admin系统,开箱即用,10分钟搭建一个美观大气的后台管理系统!

    加入我们

    我们是DevUI团队,欢迎来这里和我们一起打造优雅高效的人机设计/研发体系。招聘邮箱:muyang2@huawei.com。

    文/DevUI Kagol

    往期文章推荐

    《Quill基本使用和配置》

    《现代富文本编辑器Quill的模块化机制》

    《Quill富文本编辑器的实践》

    《如何将龙插入到编辑器中?》

    《今天是儿童节,整个贪吃蛇到编辑器里玩儿吧》


    起源地下载网 » 通过 Quill API 实现对编辑器内容的完全控制(附有查找替换功能的实现)

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元