乐趣区

关于javascript:富文本及编辑器的跨平台方案

一、前言

之前在《富文本编辑器之游戏角色降级 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 插入操作执行前,减少禁用编辑和启用编辑的切换,利用切换的时间差,将零碎键盘的主动唤起机制生效。
editor.setAttribute('contenteditable', 'false')
setTimeout(() => {editor.setAttribute('contenteditable', 'true')
}, 150)
  • Native APP 提供管制键盘弹出、收起的办法,在 Editor 须要的时候调用零碎能力实现管制自在。
JsBridge.call('updateKeyBoardState',
{keyBoardState: true/false})JsBridge.call('updateKeyBoardState',{ keyBoardState: true/false})

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

退出移动版