基于 editorjs 块编辑器开发及跨平台数据渲染
editorjs 块编辑器的开发核心是插件系统,本文主要介绍 inlineTool、blockTool 插件编写,以及将富文本解析为 JSON,实现跨平台渲染。
inlineTool 插件
每个内联工具都必须提供一个按钮(带有图标或某些布局的 HTML 元素)。按下按钮时,内联工具接收选定的文本范围作为页面上的 JavaScript 对象引用。某些工具还可能提供与用户进行其他交互的操作。
内联工具必须提供三种方法才能使用编辑器:render、surround、checkState
Render 方法必须返回内联工具栏按钮的 HTML 元素。当用户选择某些文本时,编辑器调用每个具有当前功能的内联工具的方法,以更新状态(如果所选文本包含一些内联标记)。
插件示例:
插件清单
目前支持 B(加粗)、U(下划线)、A(链接)、I(斜体),
本次增加了 FBGC(背景色) 插件。
未来将增加 FC(字体颜色)、FS(字体大小)、LH(行高)、LS(字间距)等插件。
MY富文本编辑器可配置项较多,但实际应用的功能确很少。
如图所示:
后期可根据具体需求增加块编辑器插件。
开发示例
官方文档:
https://editorjs.io/inline-tool-basics/
核心函数:
render | Required | 创建交互按钮 |
surround | Required | 所选范围添加或移除标签 |
checkState | Required | 按选定范围获取工具的激活状态 |
renderActions |
Optional | 在按钮下方创建交互界面 |
clear | Optional | 清除内联工具内容 |
1 |
|
blockTool 插件
该插件包含 BlockAPI、MenuConfig、BlockTunesAPI 三个部分,
- BlockAPI 提供了区块的渲染、保存、验证等功能。
- MenuConfig 提供了区块的菜单配置,包括图标、名称等。
- BlockTunesAPI 提供了区块的配置,包括是否可拉伸、是否可选中等。
插件示例:
插件清单
目前支持 Text(普通文本)、Heading(标题)、List(列表)、Delimiter(分隔)、Table(表格),
本次增加了 Image(图片) 插件。
未来将增加 音频、视频、融合出版应用 等插件。
开发示例
官方文档:
https://editorjs.io/the-first-plugin/
核心函数:
call(methodName:string,param?:object):void | 调用工具的实例方法 save , validate , render , etc.) |
save(): Promise<void|SavedData> | 保存块数据 |
validate(data: BlockToolData): Promise<boolean> | 验证块数据call('validate',data) |
dispatchChange() | 块已更改触发编辑器的回调onChange callback. |
config:ToolConfig | 块初始化配置 |
holder:HTMLElement | 块是否包换html标签 |
isEmpty: boolean | 块的内容是否为空 |
selected:boolean | 块是否被选中 |
stretched:boolean | 块是否被拉伸 |
1 |
|
数据转换
editorjs 的数据格式为:
1 |
|
实际上 text 字段为富文本,需要将其解析为 JSON 格式,以便跨平台渲染。
解析后的数据结构如下
1 |
|
这个数据结构清晰,在标签数量较少的情况下使用较为合适
还有一种将html转json数据结构,由于html标签很多,用树形结构较为合适
转换基本原理
节点常量类型:
常量 | 值 | 描述 |
---|---|---|
Node.ELEMENT_NODE |
1 |
一个 元素 节点,例如 <p> 和 <div> 。 |
Node.ATTRIBUTE_NODE |
2 | 元素 的耦合 属性 。 |
Node.TEXT_NODE |
3 |
Element 或者 Attr 中实际的 文字 (en-US) |
Node.CDATA_SECTION_NODE |
4 |
一个 CDATASection ,例如 <!CDATA[[ … ]]> 。 |
Node.PROCESSING_INSTRUCTION_NODE |
7 |
一个用于 XML 文档的 ProcessingInstruction (en-US) ,例如 <?xml-stylesheet ... ?> 声明。 |
Node.COMMENT_NODE |
8 |
一个 Comment 节点。 |
Node.DOCUMENT_NODE |
9 |
一个 Document 节点。 |
Node.DOCUMENT_TYPE_NODE |
10 |
描述文档类型的 DocumentType 节点。例如 <!DOCTYPE html> 就是用于 HTML5 的。 |
Node.DOCUMENT_FRAGMENT_NODE |
11 |
一个 DocumentFragment 节点 |
在项目中我们只需处理 ELEMENT_NODE 和 TEXT_NODE
递归函数解析各 childNode
使用递归函数将节点解析为JSON格式
1 |
|
跨平台数据渲染
Web
可以直接使用 text 字段及已定义的css样式进行渲染
Uniapp
开发 json-to-dom 组件,根据 ‘B’、’I’、’MARK’ 等 tag 定义不同view样式,实现Uniapp跨端渲染。
如果是自定义块,通过BlockType找到对应 标签或应用组件
例如:
BlockType = ‘audio’ 音频组件
BlockType = ‘video’ 视频组件
BlockType = ‘container_game’ 容器游戏组件
答题、电子书组件等等等等
其它平台(Android、Ios)
开发各自渲染组件
全部代码
初始化、数据解析、保存
初始化 editorjs 编辑器
1 |
|
保存数据
1 |
|