资讯专栏INFORMATION COLUMN

quill深入浅出

hlcfan / 2036人阅读

摘要:与的关系既是表达文档,又表达文档修改。然后会监听事件,然后触发的方法,传入参数,然后在的方法中,会依据构建出对应的数组,与已有的合并,使当前保持最新。

背景分析/技术选型

quill
API驱动设计,自定义内容和格式化,跨平台,易用.

CKEditor
功能强,配置灵活,ui漂亮,兼容性差

TinyMCE
文档好,功能强,bug少,无外部依赖。

UEditor
功能齐全,但是不维护了,依赖jquery,自定义起来较复杂。

功能分析

常见功能

基本文本编辑功能(加粗,加斜,字体大小,颜色等等)

文本从word复制粘贴过来后保持格式

撤销重做

扩展能力(自定义toolbar,插件(内容的扩展性))

高级功能(公式,表格等等)

结构分析 目录结构
- quill.js
- core.js
- blots/
    - block.js
    - break.js
    - container.js
    - cursor.js
    - embed.js
    - inline.js
    - scroll.js
    - text.js
- core/
    - editor.js
    - emitter.js
    - instance.js
    - logger.js
    - module.js
    - quill.js
    - selection.js
    - theme.js
- formats/
    - align.js
    - background.js
    - blockquote.js
    - bold.js
    - code.js
    - color.js
    - direction.js
    - font.js
    - formula.js
    - header.js
    - image.js
    - indent.js
    - italic.js
    - link.js
    - list.js
    - script.js
    - size.js
    - strike.js
    - table.js
    - underline.js
    - video.js
- modules/
    - clipboard.js 剪切板(复制粘贴)
    - history.js 撤销重做
    - keyboard.js 功能快捷键,可自定义
    - syntax.js 代码块语法高亮,依赖highlight.js
    - table.js 表格
    - toolbar.js 工具栏(选项可配置,工具栏html可自定义,自定义选项handlers)
    - uploader.js
- themes/
    - base.js
    - bubble.js
    - snow.js
- ui/
    - color-picker.js
    - icon.picker.js
    - icons.js
    - picker.js
    - tooltip.js

比较重要的是 quill.js, core.js, core/editor.js, core/quill.js, formats/, blots/这些目录和文件。

Quill与parchment的关系

Quill中的blots【block, break, container, cursor, embed, inline, scroll, text】和formats中的【blockquote, bold, code, formula, header, image, italic, link, list, script, strike, table, underline, video】主要利用parchment对外提供的基础Blot来作为可供继承的Blot父类

formats中的【align, background, color, direction, font, indent, size】使用 parchment对外提供的【Attributor, ClassAttributor, StyleAttributor】 来控制样式

parchment提供的Registry是用来进行blot和format的注册。

Quill与Delta的关系

delta既是表达文档,又表达文档修改。

delta作为一种描述内容修改的数据结构,承担用户操作和DOM修改之间语言的作用

delta又作为编辑器当前内容的 一种表达方式(数据源)

难点 dom修改后,如何同步到delta?

简易流程:dom mutations -> delta

ScrollBlot是最顶层的ContainerBlot, 即root Blot, 包裹所有blots, 并且管理编辑器中的内容变化。
ScrollBlot会创建一个 MutationObserver, 用来监控DOM更新。DOM更新时会调用ScrollBlot的update方法。在Quill的scroll blot中重写了update方法,其中对外抛出SCROLL_UPDATE事件和mutations参数

if (mutations.length > 0) {
  this.emitter.emit(Emitter.events.SCROLL_UPDATE, source, mutations);
}

然后editor会监听SCROLL_UPDATE事件,然后触发editor的update方法,传入mutations参数,然后在editor的update方法中,会依据mutations构建出对应的delta数组,与已有的delta合并,使当前delta保持最新。

// core/quill.js
// 监听dom修改后触发的SCROLL_UPDATE事件
this.emitter.on(Emitter.events.SCROLL_UPDATE, (source, mutations) => {
  const oldRange = this.selection.lastRange;
  const [newRange] = this.selection.getRange();
  const selectionInfo =
    oldRange && newRange ? { oldRange, newRange } : undefined;
  modify.call(
    this,
    // 依据mutations来同步更新editor对应的delta
    () => this.editor.update(null, mutations, selectionInfo),
    source,
  );
});

// core/editor.js
// 更新this.delta为最新
update(change, mutations = [], selectionInfo = undefined) {
    //...some code
    
    return change;
}
delta修改后,如何同步到dom?

简易流程:delta -> blots -> dom

例如这个API; setContents(delta: Delta, source: String = "api"): Delta

setContents传入delta后,会遍历delta数组, 生成相应的Blot, Attributor, 然后生成DOM结构,然后进行format

简易源码流程:

quill.setContents -> this.editor.applyDelta -> this.scroll.formatAt
业务实践

vue-quill-practice
中的src/components/RichTextEditor/index.vue提供一些示例, 但是因为是从业务代码中拿出来的,缺少很多依赖的东西,无法运行。仅供参考,提供思路。

主要功能

magicUrl (url文本被自动转为url链接,可点击跳转)

imageDrop (图片拖放,复制粘贴上传)

imageResize (图片缩放,水平位置调整)

mention (@人员)

预览模式点击图片自动弹层放大显示(依赖v-viewer)

自定义link按钮行为,点击弹窗填写链接名称和url, 确定后插入编辑器

自定义image按钮行为,点击选择图片并上传

自定义Quote Blot(引用块, 类似企业微信的引用块)

生态

文档:官方文档,github, 中文文档(有人翻译了,但是翻译的不好,直接看官方的吧)
插件:https://github.com/quilljs/aw...
结合vue:vue-quill-editor
结合react: react-quill

参考资料

深入理解quilljs
github quill

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/104223.html

相关文章

  • angular引入富文本ngx-quill,自定义图片上传(解决Can't resolve

    1. 安装依赖 npm i ngx-quill npm i quill ps:一定要安装 quill ,不然ngx-quill会报Cant resolve quill in xxxx, 因为ngx-quill内部引用了quill。 2. 使用 1. 引用 /* 在自己的`NgModule`的`imports`里面引用,我是在`RoutesModule`里引用的 */ import { Quil...

    willin 评论0 收藏0
  • angular引入富文本ngx-quill,自定义图片上传(解决Can't resolve

    1. 安装依赖 npm i ngx-quill npm i quill ps:一定要安装 quill ,不然ngx-quill会报Cant resolve quill in xxxx, 因为ngx-quill内部引用了quill。 2. 使用 1. 引用 /* 在自己的`NgModule`的`imports`里面引用,我是在`RoutesModule`里引用的 */ import { Quil...

    honmaple 评论0 收藏0
  • angular引入富文本ngx-quill,自定义图片上传(解决Can't resolve

    1. 安装依赖 npm i ngx-quill npm i quill ps:一定要安装 quill ,不然ngx-quill会报Cant resolve quill in xxxx, 因为ngx-quill内部引用了quill。 2. 使用 1. 引用 /* 在自己的`NgModule`的`imports`里面引用,我是在`RoutesModule`里引用的 */ import { Quil...

    hlcc 评论0 收藏0
  • 基于 Vue 的移动端富文本编辑器 vue-quill-editor 实战

    摘要:优秀的富文本编辑器有很多,比如,等,但并不是每个都能在移动端有很好的表现。是百度的老牌富文本编辑器,但界面有一股上世纪的感觉,官网最新的一条动态停留在。优秀的富文本编辑器有很多,比如:UEditor,wangEditor 等,但并不是每个都能在移动端有很好的表现。 我们暂且不讨论移动端是否真的需要富文本,既然有这需求,就把它实现出来。 失败的尝试 正确的选择是成功的开始,开发之前肯定要做一些...

    wing324 评论0 收藏0

发表评论

0条评论

hlcfan

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<