一、前言在《富文本编辑器之游戏角色升级 ing》一文中,我和大家分享了富文本编辑器的发展历程、选型技巧和扩展方案。今天和大家聊聊“富文本和编辑器跨平台解决方案”。您应该注意到标题使用“富文本和编辑器”而不是“富文本编辑器”。也就是说,本文将重点关注富文本跨平台和编辑器跨平台两大块。通过跨平台解决方案的分享,希望能给有富文本编辑器跨平台相关需求的朋友带来一些帮助。二、为什么要跨平台对于一个产品来说,用户需求的程度在一定程度上反映了其产品的价值。对于富文本编辑器来说,WEB端(PC浏览器、手机浏览器)、移动端(IOS应用、Android应用)、桌面端(windows、macOS)的系统生态已经不能满足用户的需求。需要。同时,对于研发人员来说,每一端都需要大量的资源去开发重复性的能力,这无疑是一种资源消耗。因此,越来越多的团队开始寻求突破,建立跨平台的编辑生态,实现不同平台、不同终端的数据互通,展示具有一致体验的编辑能力。(图片来自网络)以上是一个比较笼统的概念。举个例子说明一下:对于社交应用,以微博中的场景为例:如果你用电脑网页版的微博发布了一篇长文,然后分享给你的朋友,期间发现内容可能需要编辑。这时问题来了,你是倾向于放下手机打开电脑编辑,还是直接切换到手机微博编辑。我猜绝大多数小伙伴应该会选择使用手机微博来编辑,那么我们可以发现,在这个过程中,我们经历了Web端发布-微信小程序端查看-APP端编辑等几个阶段.其实就是跨平台操作。记录类应用以手机端的笔记应用为例:越来越多的用户习惯用笔记等应用来记录一些生活事项,那么这些记录是否只存在于本地?不!如果只存储在本地,换手机或清空数据后就无法找回数据,这当然不符合大众的需求。录音应用的大部分数据都存储在云端。使用云存储不仅可以满足跨设备的数据迁移,还可以带来跨平台可浏览、可编辑、可删除的附加值。以上简单介绍了跨平台富文本编辑器的两个应用场景,可见跨平台富文本编辑器已经成为必然需求。既然清楚了为什么要跨平台,那么接下来就是讨论如何实现跨平台了。3、富文本跨平台富文本指的是这里的“编辑器输出的数据”。富文本的跨平台,本质上就是让富文本在不同的平台上以原生的方式展现相同的效果。注:本章讨论的场景主要是WEB端的富文本HTML如何在Android和小程序中显示原生效果。有朋友可能会问,HTML在Android中可以使用HTML.fromHtml方法解析显示富文本内容。微信小程序也可以直接用富文本组件渲染。既然HTML可以跨平台展示,为什么要单独开一章来讨论呢?对于这个问题,首先给大家展示下在不同平台使用HTML数据渲染可能会出现的问题:从上图可以看出,HTML的优点是功能丰富,灵活多变.也正因为如此,很难严格定义数据。因此,如果使用HTML作为传输数据,很容易在不同平台上出现解析兼容问题。那么,为了在不同的平台上实现一致的显示效果,有两种方案可供参考:方案一:强行将HTML转换为能够正常适配各个平台的层次结构。方案二:使用通用的数据模型,每一端都可以解析,每一端都使用原生组件进行解析和渲染。方案一可以通过枚举不兼容的场景,将源数据转换成所有平台都能正常解析的HTML,但是从可扩展性的角度,枚举替换不太现实。既然如此,我们就来看看如何通过第二种方案来实现吧。通用数据模型考虑到HTML转换中的问题,通用数据模型需要满足以下条件:描述文档层次结构严格定义嵌套规则制定数据过滤机制下图比较了使用JSON和XML作为数据模型的优缺点,可以根据项目需要选择:之前分享的文章中,富文本编辑器在L2阶段的数据模型多为JSON结构。本节直接用前面的例子来介绍JSON数据模型是如何满足以上三个条件的。:遵循条件规范,定义数据模型,平台间数据传递的过程如下图所示:整个过程总结如下:以通用数据模型为媒介,打通WEB之间的连接终端与安卓和小程序数据互通,使用原生组件在各个平台渲染页面,最终实现跨平台富文本。本节要解决的问题是:如何在各个平台上获得最原始的WEB端制作的富文本内容展示效果。那么如何保证各个平台输出相同的数据模型呢?这也引入了下一节的内容——跨平台编辑器。4、编辑器跨平台编辑器是跨平台的,就是各个平台提供功能模块,WEB端提供排版和编辑能力,最终运行在特定平台的浏览器环境中。本节以AndroidApp编辑器的实现为例,其他平台编辑器的实现原理相同。以签名APP为例,富文本内容编辑模块运行在NativeApp提供的Webview环境中,其工具栏菜单和状态显示部分由NativeApp原生控件组成。为什么不选择直接使用Native编辑器或者Web编辑器,而是选择这样的组合呢?首先,如果选择单一的编辑器,或多或少都会存在一些问题,例如:Native编辑器实现复杂的富文本结构的开发成本比较高,需要自定义很多功能模块;Web编辑器在NativeAPP中操作能力有限,交互体验不如Native原生控件。然后两者“取其精华”,选择保留富文本在web端丰富灵活的排版能力,同时使用Native原生控件关联用户操作,最终达到1+1>2的效果.具体体现在:富文本内容的灵活展示;不同平台的核心编辑代码可以复用,降低跨平台编辑器的开发成本;具有系统级控制权限,大大扩展了编辑器(语音、图片)编辑等能力;4.1如何实现跨平台编辑器?跨平台编辑器有两个关键问题需要解决:NativeApp和运行在webview中的编辑器之间如何进行数据通信?Native工具栏如何根据光标位置呈现不同的状态?首先介绍一下跨平台编辑器以及模块之间的交互方式。编辑器会打开setData、getData、execCommand等接口供NativeAPP调用,为编辑器添加内容。NativeAPP也会给编辑器提供一些接口,比如viewLoad、requestMedia、updateBtnStatus。编辑器可以根据自己的状态通过这些接口向APP传输一些数据或者信号,从而刷新APP中各个控件的状态。Web编辑器只与NativeAPP建立通信,与服务端的数据交互由NativeAPP完成。下面将介绍几款跨平台编辑器的核心场景实现,供大家参考。4.1.1页面初始化跨平台编辑器的编辑页面由NativeAPP和Webview中的WebEditor组成,也就是说页面的初始化需要两个模块的配合。一般情况下,NativeAPP中原生控件的渲染速度要快于Webview。这里,Editor加载完成后,调用NativeAPP提供的初始化方法,将NativeAPP从Loading状态切换到完成状态。假设此时有保存的草稿,可以在页面加载后直接调用Editor对外暴露的setData方法初始化编辑器数据。4.1.2数据通信在剪辑过程中,NativeAPP和剪辑师之间必须有双向通信。以简单的插入表情为例。整个操作流程分为以下几个步骤:1.点击表情按钮,从键盘状态切换到表情选择面板,此时都属于NativeAPP内部操作流程。2、点击表情时,NativeAPP需要主动与小编建立联系,通知小编需要插入表情。3、编辑器收到插入表情的指令后,插入从NativeAPP传来的表情数据,同时触发编辑器内部状态刷新,如统计字数、刷新历史记录等。4.由于当前的撤消和重做按钮已经不在编辑器内部了,当刷新历史时,需要重新设置按钮的状态。此时小编需要调用NativeAPP提供的状态刷新方法,通知NativeAPP更新按钮状态。这样就完成了两个模块之间的双向数据通信。4.1.3MediaEmbeddingMediaEmbedding是富文本编辑器中必不可少的部分,这里单独介绍,主要是因为跨平台的富文本编辑器在向服务器上传资源时,并不常规通过编辑器。自己实现的。中间的处理逻辑是什么?NativeAPP图片选择的过程我就不多说了,直接进入选择后上传的部分。NativeAPP选中图片后,会直接调用服务端的接口上传图片,同时携带选中的图片信息(本地路径、宽高信息等)给编辑器.由于图片上传和图片插入有一定的时间差,编辑器最初收到插入图片的命令后,默认为加载状态,等待NativeAPP上传完成的信号。当服务端接口返回图片加载完成信息时,NativeAPP调用编辑器预先提供的接口,控制编辑器中某张图片的刷新为完成时态。这样就实现了资源的上传和插入:4.2踩坑实践了解一下!当然,并非一切都是一帆风顺的。在开发过程中,也踩了一些坑,分享给大家。4.2.1键盘控制预览:由于我使用的网页编辑器仍然依赖于浏览器的contenteditable特性,以下案例不具有普遍性,仅供参考。基于contenteditable编辑器,当插入光标时,会自动唤起手机输入法键盘。在某些场景下,比如插入图片后,预计键盘会关闭。但在实际操作中,默认会调用键盘,即系统键盘不受编辑器控制。针对这种情况,我尝试了一些解决方案,最终选择了双管齐下,增加双保险:在执行Editor插入操作之前,添加一个禁止编辑和允许编辑的开关,利用时间差自动唤醒系统键盘的开关。机制失效。editor.setAttribute('contenteditable','false')setTimeout(()=>{editor.setAttribute('contenteditable','true')},150)NativeAPP提供了控制弹出和关闭的方法键盘,在编辑器调用系统能力时需要,实现控制自由。JsBridge.call('updateKeyBoardState',{keyBoardState:true/false})JsBridge.call('updateKeyBoardState',{keyBoardState:true/false})4.2.2资源失败重试在编辑器中,资源上传失败会配备一个重新上传机制。在跨平台编辑器中,需要在WEB编辑器中触发重新上传,NativeAPP会重新上传。NativeAPP上传图片的前提是获取图片的本地路径。因此,在前期设计中需要重点关注以下几点:NativeAPP在调用编辑器接口插入图片时,需要告知图片对应的本地路径,也作为参考条件后续状态刷新和失败重试。需要增加对本地路径异常失败的处理(删除本地图片、移动等)。看完这里,你对如何实现一个跨平台的富文本编辑器有什么打算了吗?本节只讨论AndroidAPP平台的场景,其他平台同理。例如,在桌面平台(Windows、Mac)的客户端,可以选择使用CEF(ChromiumEmbeddedFrameWork)来提供浏览器环境。有兴趣的朋友可以试试看。五、总结本文从富文本跨平台和编辑器跨平台两个角度,分析了为什么要通过跨平台方案来实现富文本编辑器,以及如何实现两种类型的跨平台,其中重点介绍了跨平台编辑器的核心流程和踩坑实践。至此,富文本编辑器的分享就告一段落了。通过这个内容的介绍,希望大家在遇到这样的需求时,能够举一反三,顺利实施方案。参考资料1.富文本|微信开放文档(opensnewwindow)2.有道云笔记跨平台富文本编辑器的技术演进作者:vivo互联网前端团队-田雨涵
