摘要:与的关系既是表达文档,又表达文档修改。然后会监听事件,然后触发的方法,传入参数,然后在的方法中,会依据构建出对应的数组,与已有的合并,使当前保持最新。
背景分析/技术选型
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
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...
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...
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...
摘要:优秀的富文本编辑器有很多,比如,等,但并不是每个都能在移动端有很好的表现。是百度的老牌富文本编辑器,但界面有一股上世纪的感觉,官网最新的一条动态停留在。优秀的富文本编辑器有很多,比如:UEditor,wangEditor 等,但并不是每个都能在移动端有很好的表现。 我们暂且不讨论移动端是否真的需要富文本,既然有这需求,就把它实现出来。 失败的尝试 正确的选择是成功的开始,开发之前肯定要做一些...
阅读 2935·2023-04-26 02:29
阅读 549·2019-08-30 15:54
阅读 1618·2019-08-29 13:13
阅读 521·2019-08-28 17:51
阅读 2682·2019-08-26 13:58
阅读 1501·2019-08-26 13:27
阅读 2794·2019-08-26 11:39
阅读 3408·2019-08-26 10:46