Draft.js的数据结构

JavaScript027

Draft.js的数据结构,第1张

Draft.js 使用EditorState来保存数据结构顶层,其中记录了用于展示数据的所有数据结构。本文将通过提供一系列的简单示例来简单介绍 Draft.js 的数据结构。

Draft.js 基于 immutable.js 实现了一种不可变的数据结构,基于这种数据结构, Draft.js 实现了单项数据流,即 event ->onChange ->EditorState

我在 CodePen 上面实现了一个简单的Demo用于展示EditorState,你可以在上面尝试一下。

上图展示了一个完整的EditorState,我们可以轻易的猜测出一些属性的含义,比如currentContent记录了当前编辑器中展示内容的状态,selection中标识当前的选区,redoStack和undoStack分别是撤销、重做栈,而EditorState则提供了操作这些属性的顶层方法。

Draft 将样式分为块级样式与内联样式,块级样式之间线性排列,不可嵌套,内联样式则用数组记录,可以重叠。

当我在 draft 中随意输入一些文字的时候,text将会记录下文字内容,而此时用于记录块级样式的type值为 unstyled

现在我们将H1(块级元素)应用于文本,我们可以发现用于标识块级样式的type值变为了 header-one ,当我们继续在该行输入的时候,将会同样被赋予H1样式。通过上述的数据结构我们可以发现,由于块级样式由type所规定,所以块级样式之间不可被嵌套,即不会出现无序列表嵌套有序列表的情况出现。

对于同一块级元素中的文本内容, draft 将其按照字符进行拆分,每一个字符的内联样式用数组进行展示,由此可以解决内联样式的嵌套问题。

Entity并不是一个难以理解的数据类型,Entity数据主要用于展示一些不可被分割的数据类型,例如图片、mention、超链接等。

典型场景就是mention类型,详细来说,我们在日常使用中会在富文本编辑器中提及一些人, @xxx 的数据类型要求是一个统一整体,一旦 @xxx 中有某一个字符被删除,就有可能会出现 @ 出的名字和 @ 的对象不一致的情况。

在上图中,我将插入的图片数据结构打印了出来,我们可以发现这是一个Entity,记录了data,mutability与type, Draft.js 向外暴露了一个顶层接口,当Entity数据被注入的时候,可以通过这个接口来设计数据对象的展现方式,如下图

又来了

https://www.draft-js-plugins.com/plugin/image

draft.js:不要使用redux来管理editorState

draft.js:让光标显示在最后面

draft.js:内容清空之后,光标的位置会错乱

draft.js:如何改变 draft.js 编辑框的高度

draft.js:getPlainText 对换行符的修改 (填坑篇)

draft.js:onChange改装,判断文字内容是否修改

draft.js--富文本编辑器框架的实践(一)

draft.js--富文本编辑器框架的实践(二)

原 1.Draftjs 学习笔记

原 2.Draftjs 学习笔记-Rich Styling

原 3.Draftjs 学习笔记-Entities

原 4.Draftjs 学习笔记-Decorators

原 5.Draftjs 学习笔记-自定义控件(多媒体)

原 6.Draftjs 学习笔记-聊聊自定义样式

原 7.Draftjs 学习笔记-StateToHtml

Draftjs中文翻译1 - 概观

Draftjs中文翻译2 - API Basics API基础

Draftjs中文翻译3 - Rich Styling丰富的造型

Draftjs中文翻译4- 实体

Draftjs中文翻译5 - v0.10 API迁移

Draft.js文档

使用 Draft.js 来构建一个现代化的编辑器

draft.js在知乎的实践

基于Draft.js自定义富文本编辑器

基于Draftjs实现的Electron富文本聊天输入框

基于Draftjs实现的Electron富文本聊天输入框(一) —— 群@功能

基于Draftjs实现的Electron富文本聊天输入框(二) —— 图文输入

基于Draftjs实现的Electron富文本聊天输入框(三) —— Emoji

基于Draftjs实现的Electron富文本聊天输入框(四) —— 自定义快捷键

基于Draftjs实现的Electron富文本聊天输入框(五) —— 问题总结与解决

完美解决问题!

还有下一个问题:光标位置错乱 待解决!!!

<html>

<body>

<select name="select" onchange="on_test(this.value)">

<option value="1_值1">默认值</option>

<option value="0_值1">名称1</option>

<option value="1_值2">名称2</option>

</select>

<input id="ygyjmb">

<script type="text/javascript">

function on_test(val){

if (val.charAt(0)=="0"){

document.getElementById("ygyjmb").readOnly=true

}else{

document.getElementById("ygyjmb").readOnly=false

}

}