富文本及编辑器的跨平台方案
一、前言
之前在《富文本編輯器之游戲角色升級 ing》一文中,跟大家分享了富文本編輯器的發展歷程、選型技巧和擴展方案。今天將和大家一起聊一聊“富文本及編輯器跨平臺方案”那些事。
大家應該注意到了,標題用的是“富文本及編輯器”,而非“富文本編輯器”。也就意味著本文將圍繞富文本跨平臺和編輯器跨平臺兩大部分進行介紹。
通過跨平臺方案的分享,希望能給有富文本編輯器跨平臺相關需求的小伙伴帶來一些幫助。
二、為什么要跨平臺
對于一個產品來說,用戶的需求程度在一定程度上反映了其產品的價值。對于富文本編輯器而言,以?WEB 端(PC 瀏覽器、移動瀏覽器)、移動端(IOS 應用、Android 應用)、桌面端(windows、macOS)各自為戰的系統生態,已經無法滿足用戶的需求。同時對于研發人員而言,各端都需要大量的資源投入進行重復能力的開發,這無疑是一種資源的消耗。因此越來越多的團隊開始尋求突破,建立跨平臺的編輯生態,在不同的平臺、不同的終端上實現數據互通,展現體驗一致的編輯能力。
(圖片來源于網絡)
上面是比較籠統的概念,舉例子說明下:
社交類型的應用
以微博中的場景為例:假如你用電腦網頁版微博發布了一篇長文,然后分享給了你的朋友,期間發現內容可能需要編輯下。這個時候問題來了,你是傾向于放下手機打開電腦編輯,還是直接切到手機微博來編輯。我猜絕大多數小伙伴應該會選擇用手機微博進行編輯,那么我們就可以發現在這個過程中經歷了?Web 端發表–微信小程序查看–APP 端編輯幾個階段,這其中的流轉其實就是跨平臺操作。
記錄類型的應用
以手機端便簽應用為例:越來越多的用戶習慣用便簽之類的應用記錄一些生活事項,那這些記錄是僅存儲在本地設備中的嗎?NO! 如果僅存儲在本地,那么換臺手機或者清除數據后,數據就無法找回了,這必然不符合大眾的需求。大部分記錄類應用的數據是存儲在云端的,使用云端存儲既能滿足跨設備的數據遷移,同時帶來了跨平臺可瀏覽、可編輯、可刪除的附加價值。
以上,簡單介紹了富文本編輯器跨平臺的兩個應用場景,可以看出富文本編輯器跨平臺已經成為一種必然的需要。既然已經清晰了為什么要跨平臺,下一步我們就來探討下如何實現跨平臺。
三、富文本跨平臺
富文本,在這里指代“編輯器所輸出的數據”。富文本的跨平臺,實質上就是使富文本在不同平臺內以其原生的方式展示相同的效果。
注:在本章節中探討的場景主要是 WEB 端的富文本 HTML 如何可以在 Android、小程序中展示原生的效果。
有朋友也許會問,HTML 在 Android 內可以用 HTML.fromHtml 方法解析展示富文本內容。微信小程序也可以用 rich-text 富文本組件直接渲染,既然用 HTML 就可以跨平臺展示,為什么還要單獨拆分一個章節探討呢?對于這個問題,首先給大家分別展示下用 HTML 數據渲染在不同平臺中可能出現的問題:
從上圖中可以看出,HTML的優點是特性豐富,靈活多變。而正因如此,其很難嚴格的定義數據。因此若是將HTML作為流轉的數據,很容易在不同平臺內出現解析兼容問題。
那么要在不同平臺間實現一致的展示效果,有兩種方案作為參考:
-
方案一:將 HTML 強制轉化為各平臺都能正常適配的層級結構。
-
方案二:利用一種通用的可供各端解析的數據模型,各端用原生組件解析渲染。
方案一雖然可以通過枚舉不兼容的場景正則替換,將源數據轉化為各平臺均可以正常解析的 HTML,但是從可擴展性的角度上來說,枚舉替換的方案不太現實。既然如此,那就一起看看如何通過方案二實現。
通用的數據模型
考慮到 HTML 轉化中存在的問題,那么通用的數據模型需要滿足以下條件:
-
描述文檔層級結構
-
嚴格定義嵌套規則
-
制定數據過濾機制
下圖分別對比了使用 JSON、XML 作為數據模型的優缺點,可以根據項目需要酌情選擇:
之前分享的文章中,L2 階段的富文本編輯器的數據模型多是 JSON 結構,本節直接沿用之前的例子展開介紹下 JSON 數據模型是如何滿足以上三個條件的:
遵循條件規范,定義好數據模型后,此時數據在各平臺間的流轉過程就如下圖所示:
整個流程總結下來就是:以通用數據模型作為媒介,打通 WEB 端與 Android、小程序的數據互通,在各平臺用原生的組件渲染頁面,最終實現富文本的跨平臺。
本節解決的問題是:WEB 端產出的富文本內容,在各平臺如何得到最本源的展示效果。那么如何保證各個平臺都是輸出相同的數據模型呢?這也就引入了下節的內容——編輯器的跨平臺。
四、編輯器跨平臺
編輯器跨平臺,是指由各平臺提供功能模塊,WEB 端提供排版編輯能力,最終運行在平臺特定的瀏覽器環境中。本節將以 Android App 的編輯器實現為例進行展開,其他平臺的編輯器實現原理相同。
以便簽 APP 為例,富文本內容編輯模塊運行在由Native App 提供的 Webview 環境中,其工具欄菜單、狀態顯示部分則由 Native App 原生控件組成。
為什么不選擇直接用 Native 編輯器或者 Web 編輯器,而是選擇這樣組合的形式呢?
首先,如果選擇單一的編輯器或多或少存在一些問題,比如說:
-
Native 編輯器實現復雜富文本結構的開發成本較高,需要定制很多功能模塊;
-
Web 編輯器在 Native APP 中操作能力有限,且交互體驗不及 Native 原生控件。
那么兩者“取其精華”,選擇保留 Web 端富文本豐富靈活的排版能力,同時用 Native 原生控件關聯用戶操作,最終實現 1+1>2 的效果。具體體現在:
-
靈活展示豐富的富文本內容;
-
不同平臺的核心編輯代碼可復用,降低跨平臺編輯器的開發成本;
-
具備系統級控制權限,極大地擴展了編輯器的能力組成(語音、圖片編輯等);
4.1 如何實現一個跨平臺的編輯器?
跨平臺編輯器重點需要解決的問題有兩點:
Native App 與運行在 webview 中的編輯器如何數據通信?
Native 工具欄如何跟隨光標位置呈現不同的狀態?
首先,介紹下跨平臺的編輯器,各模塊之間是如何交互的。
-
編輯器會開放一些接口如 setData、getData、execCommand,供 Native APP 調用,向編輯器內添加內容。
-
Native APP 也會向編輯器提供一些接口,如 viewLoad、requestMedia、updateBtnStatus。編輯器可以根據自身的狀態,通過這些接口向 APP 內傳遞一些數據或者信號,使得 APP 內的各種控件狀態得到刷新。
-
Web 編輯器僅與 Native APP 建立通信,與服務端的數據交互交由 Native APP 完成。
下面,將介紹幾個跨平臺編輯器的核心場景實現,供大家參考。
4.1.1 頁面初始化
跨平臺編輯器的編輯頁由 Native APP 和 Webview 中的 Web Editor 組成,那么意味著頁面的初始化需要兩個模塊協同實現。
一般情況下 Native APP 中原生控件的渲染速度是要快于 Webview 的渲染,這里可以在 Editor loaded 之后,調用 Native APP 提供的初始化方法,將 Native APP 從 Loading 狀態切換至完成態。
假設此時保存有草稿,可以在頁面 Load 后,直接調用 Editor 暴露的 setData 方法,初始化編輯器數據。
4.1.2 數據通信
在編輯過程中,必然存在 Native APP 與 編輯器的雙向通信,就以簡單的插入表情為例,整個操作流程分為以下幾個步驟:
1、點擊表情按鈕,從鍵盤狀態切換至表情選擇面板,此時都屬于 Native APP 內部操作流程。
2、當點擊某個表情后,就需要 Native APP 主動與編輯器建立通信,通知編輯器需要執行插入表情的操作。
3、編輯器接收到插入表情的指令后,插入 Native APP 流轉過來的表情數據,同時觸發了編輯器內部的狀態刷新,比如說字數計算、歷史記錄的刷新。
4、由于現在的撤銷、重做按鈕已經不在編輯器內部,當歷史記錄刷新時,需要對按鈕的狀態進行重置。這個時候就需要編輯器調用 Native APP 提供的狀態刷新方法,通知 Native APP 進行按鈕狀態的更新。
這樣就完成了兩個模塊的雙向數據通信。
4.1.3 媒體嵌入
媒體嵌入是富文本編輯器中必不可少的一部分,這里單獨拿出來介紹,主要是因為跨平臺的富文本編輯器在上傳資源到服務端時,并不是常規的通過編輯器本身來實現的。那中間的處理邏輯是怎樣的呢?
Native APP 圖片選擇的流程就不過多贅述,直接進入到選擇之后上傳的部分。Native APP 選擇圖片之后,直接會調用服務端的接口將圖片上傳,與此同時還會攜帶選擇的圖片信息(本地路徑、寬高信息等等)傳遞給編輯器。
由于圖片上傳與圖片插入存在一定時間差,所以編輯器在最初接收到插入圖片的命令后,默認處理為 loading 狀態,等待 Native APP 上傳完成的信號。
當服務端接口返回圖片加載完成的信息后,Native APP 調用編輯器預先提供的接口,控制編輯器中某張圖片刷新為完成時態。這樣就實現了資源的上傳及插入:
4.2 踩坑實踐了解一下!
當然,不是所有的事情都是一帆風順的。我在開發過程中,也踩了一些坑,跟大家分享下。
4.2.1 鍵盤的控制
預告:由于我使用的 Web 編輯器仍然依賴瀏覽器的 contenteditable 特性,所以下面的案例,并不具備普適性,大家僅供參考。
基于 contenteditable 的編輯器,在光標插入的時候,會自動喚起手機端的輸入法鍵盤。有些場景下,比如插入圖片后,預期鍵盤處于關閉狀態。但是在實際操作時,鍵盤會默認喚起,即系統鍵盤不受編輯器控制。
針對這種情況,我嘗試了一些解決方案,最終選擇采用雙管齊下的方式,增加雙重保險:
- 在 Editor 插入操作執行前,增加禁用編輯和啟用編輯的切換,利用切換的時間差,將系統鍵盤的自動喚起機制失效。
- Native APP 提供控制鍵盤彈出、收起的方法,在 Editor 需要的時候調用系統能力實現控制自由。
4.2.2 資源的失敗重試
在編輯器中,資源上傳失敗均會配備重新上傳的機制。在跨平臺編輯器中,重新上傳需要在 WEB 編輯器中觸發,交由Native APP 重新上傳。Native APP上傳圖片的前提是拿到圖片的本地路徑。因此在前期設計時就需要重點關注以下幾個點:
-
Native APP 在調用編輯器插入圖片的接口時,就需要告知圖片對應的本地路徑,也作為后續狀態刷新、失敗重試的參照條件。
-
要增加本地路徑異常失效的處理(本地圖片刪除、移動等)。
讀到這里,各位小伙伴對于如何實現一個跨平臺的富文本編輯器,是否已經胸有成竹了呢。本節只是探討了?Android APP?這一種平臺的場景,對于其他的平臺其實也是如此,比如桌面端平臺(Windows、Mac)的客戶端中,可以選擇用 CEF(Chromium Embedded FrameWork)提供瀏覽器環境。感興趣的小伙伴可以動手嘗試一下。
五、總結
本篇文章聚焦富文本跨平臺和編輯器跨平臺兩個角度,分析了為什么要通過跨平臺的方案實現富文本 編輯器、以及如何實現兩類的跨平臺,其中重點介紹了跨平臺編輯器的核心流程和踩坑實踐。
到此,關于富文本編輯器的分享已經接近尾聲。通過這篇內容的介紹,希望大家在遇到諸如此類的需求時,可以觸類旁通,順順利利的將方案落地。
參考資料
1、rich-text |微信開放文檔(opens new window)
2、有道云筆記跨平臺富文本編輯器的技術演進
作者:vivo互聯網服務器團隊-Tian Yuhan
總結
以上是生活随笔為你收集整理的富文本及编辑器的跨平台方案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 谷歌网盘云盘google drive扩容
- 下一篇: python实现KNN算法并可视化展示