摘要:與的關(guān)系既是表達(dá)文檔,又表達(dá)文檔修改。然后會(huì)監(jiān)聽事件,然后觸發(fā)的方法,傳入?yún)?shù),然后在的方法中,會(huì)依據(jù)構(gòu)建出對(duì)應(yīng)的數(shù)組,與已有的合并,使當(dāng)前保持最新。
背景分析/技術(shù)選型
quill
API驅(qū)動(dòng)設(shè)計(jì),自定義內(nèi)容和格式化,跨平臺(tái),易用.
CKEditor
功能強(qiáng),配置靈活,ui漂亮,兼容性差
TinyMCE
文檔好,功能強(qiáng),bug少,無(wú)外部依賴。
UEditor
功能齊全,但是不維護(hù)了,依賴jquery,自定義起來(lái)較復(fù)雜。
常見功能
基本文本編輯功能(加粗,加斜,字體大小,顏色等等)
文本從word復(fù)制粘貼過來(lái)后保持格式
撤銷重做
擴(kuò)展能力(自定義toolbar,插件(內(nèi)容的擴(kuò)展性))
高級(jí)功能(公式,表格等等)
結(jié)構(gòu)分析 目錄結(jié)構(gòu)- 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 剪切板(復(fù)制粘貼) - history.js 撤銷重做 - keyboard.js 功能快捷鍵,可自定義 - syntax.js 代碼塊語(yǔ)法高亮,依賴highlight.js - table.js 表格 - toolbar.js 工具欄(選項(xiàng)可配置,工具欄html可自定義,自定義選項(xiàng)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的關(guān)系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對(duì)外提供的基礎(chǔ)Blot來(lái)作為可供繼承的Blot父類
formats中的【align, background, color, direction, font, indent, size】使用 parchment對(duì)外提供的【Attributor, ClassAttributor, StyleAttributor】 來(lái)控制樣式
parchment提供的Registry是用來(lái)進(jìn)行blot和format的注冊(cè)。
Quill與Delta的關(guān)系delta既是表達(dá)文檔,又表達(dá)文檔修改。
delta作為一種描述內(nèi)容修改的數(shù)據(jù)結(jié)構(gòu),承擔(dān)用戶操作和DOM修改之間語(yǔ)言的作用
delta又作為編輯器當(dāng)前內(nèi)容的 一種表達(dá)方式(數(shù)據(jù)源)
難點(diǎn) dom修改后,如何同步到delta?簡(jiǎn)易流程:dom mutations -> delta
ScrollBlot是最頂層的ContainerBlot, 即root Blot, 包裹所有blots, 并且管理編輯器中的內(nèi)容變化。
ScrollBlot會(huì)創(chuàng)建一個(gè) MutationObserver, 用來(lái)監(jiān)控DOM更新。DOM更新時(shí)會(huì)調(diào)用ScrollBlot的update方法。在Quill的scroll blot中重寫了update方法,其中對(duì)外拋出SCROLL_UPDATE事件和mutations參數(shù)。
if (mutations.length > 0) { this.emitter.emit(Emitter.events.SCROLL_UPDATE, source, mutations); }
然后editor會(huì)監(jiān)聽SCROLL_UPDATE事件,然后觸發(fā)editor的update方法,傳入mutations參數(shù),然后在editor的update方法中,會(huì)依據(jù)mutations構(gòu)建出對(duì)應(yīng)的delta數(shù)組,與已有的delta合并,使當(dāng)前delta保持最新。
// core/quill.js // 監(jiān)聽dom修改后觸發(fā)的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, // 依據(jù)mutations來(lái)同步更新editor對(duì)應(yīng)的delta () => this.editor.update(null, mutations, selectionInfo), source, ); }); // core/editor.js // 更新this.delta為最新 update(change, mutations = [], selectionInfo = undefined) { //...some code return change; }delta修改后,如何同步到dom?
簡(jiǎn)易流程:delta -> blots -> dom
例如這個(gè)API; setContents(delta: Delta, source: String = "api"): Delta
setContents傳入delta后,會(huì)遍歷delta數(shù)組, 生成相應(yīng)的Blot, Attributor, 然后生成DOM結(jié)構(gòu),然后進(jìn)行format
簡(jiǎn)易源碼流程:
quill.setContents -> this.editor.applyDelta -> this.scroll.formatAt業(yè)務(wù)實(shí)踐
vue-quill-practice
中的src/components/RichTextEditor/index.vue提供一些示例, 但是因?yàn)槭菑臉I(yè)務(wù)代碼中拿出來(lái)的,缺少很多依賴的東西,無(wú)法運(yùn)行。僅供參考,提供思路。
magicUrl (url文本被自動(dòng)轉(zhuǎn)為url鏈接,可點(diǎn)擊跳轉(zhuǎn))
imageDrop (圖片拖放,復(fù)制粘貼上傳)
imageResize (圖片縮放,水平位置調(diào)整)
mention (@人員)
預(yù)覽模式點(diǎn)擊圖片自動(dòng)彈層放大顯示(依賴v-viewer)
自定義link按鈕行為,點(diǎn)擊彈窗填寫鏈接名稱和url, 確定后插入編輯器
自定義image按鈕行為,點(diǎn)擊選擇圖片并上傳
自定義Quote Blot(引用塊, 類似企業(yè)微信的引用塊)
生態(tài)文檔:官方文檔,github, 中文文檔(有人翻譯了,但是翻譯的不好,直接看官方的吧)
插件:https://github.com/quilljs/aw...
結(jié)合vue:vue-quill-editor
結(jié)合react: react-quill
深入理解quilljs
github quill
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/104223.html
1. 安裝依賴 npm i ngx-quill npm i quill ps:一定要安裝 quill ,不然ngx-quill會(huì)報(bào)Cant resolve quill in xxxx, 因?yàn)閚gx-quill內(nèi)部引用了quill。 2. 使用 1. 引用 /* 在自己的`NgModule`的`imports`里面引用,我是在`RoutesModule`里引用的 */ import { Quil...
1. 安裝依賴 npm i ngx-quill npm i quill ps:一定要安裝 quill ,不然ngx-quill會(huì)報(bào)Cant resolve quill in xxxx, 因?yàn)閚gx-quill內(nèi)部引用了quill。 2. 使用 1. 引用 /* 在自己的`NgModule`的`imports`里面引用,我是在`RoutesModule`里引用的 */ import { Quil...
1. 安裝依賴 npm i ngx-quill npm i quill ps:一定要安裝 quill ,不然ngx-quill會(huì)報(bào)Cant resolve quill in xxxx, 因?yàn)閚gx-quill內(nèi)部引用了quill。 2. 使用 1. 引用 /* 在自己的`NgModule`的`imports`里面引用,我是在`RoutesModule`里引用的 */ import { Quil...
摘要:優(yōu)秀的富文本編輯器有很多,比如,等,但并不是每個(gè)都能在移動(dòng)端有很好的表現(xiàn)。是百度的老牌富文本編輯器,但界面有一股上世紀(jì)的感覺,官網(wǎng)最新的一條動(dòng)態(tài)停留在。優(yōu)秀的富文本編輯器有很多,比如:UEditor,wangEditor 等,但并不是每個(gè)都能在移動(dòng)端有很好的表現(xiàn)。 我們暫且不討論移動(dòng)端是否真的需要富文本,既然有這需求,就把它實(shí)現(xiàn)出來(lái)。 失敗的嘗試 正確的選擇是成功的開始,開發(fā)之前肯定要做一些...
閱讀 3007·2023-04-26 02:29
閱讀 617·2019-08-30 15:54
閱讀 1704·2019-08-29 13:13
閱讀 631·2019-08-28 17:51
閱讀 2753·2019-08-26 13:58
閱讀 1560·2019-08-26 13:27
閱讀 2844·2019-08-26 11:39
閱讀 3474·2019-08-26 10:46