完全可定制的富文本编辑框架——Slate.js

JavaScript013

完全可定制的富文本编辑框架——Slate.js,第1张

Slate 是一个完全可定制的富文本编辑框架。通过 Slate,你可以构建出类似 Medium、Dropbox Paper 或者 Canvas 这样使用直观、富交互、体验也已成为 Web 应用标杆的编辑器。Slate 本身并不是一个编辑器,而是一套在 React 和 Immutable 的基础上,用于操作富文本数据的框架。基于 Slate 实现一个富文本编辑器,相当于是使用 React(视图层)+ Immutable(数据层)开发一个普通 Web 应用,Slate相当于Controller。

Github:

文档:

在线示例:

使用npm包管理

Slate 开放了一套用于构建编辑器的模块。其中,最重要的是 Editor 组件:

启动的时候我第一次失败了,然后重新启动下就行了,然后打开浏览器localhost:8080

通过简单的语法实现Markdown的编写

你可以从别的网站直接粘贴带有样式的文本

写过html标签的都知道

类似<textarea></textarea>

可以在应用某些更改后保存新版本,然后随时回滚到以前的版本

以下是开发者的一些说明(文档有中文版):

类似加粗和斜体的结构可以开箱即用,但评论、嵌入内容以及更多的定制性需求呢?

用户的编写体验可能不错,但在执行编程式变更时却不必要地复杂,而这对于构建高级的编辑行为至关重要。

这是一个非常常见的使用场景,但要实现将文档转换为 HTML 或 Markdown 的简单功能都需要编写大量的模板代码。

各种编辑器在重新发明视图层的轮子,而非使用 React 这样已有的技术方案。你必须学习一套带着自有限制和陷阱的新系统。

编辑器内部的数据结构使其无法用于实时、协作的编辑场景中,除非重写编辑器。

许多编辑器没有对外开放本应为开发者所复用的内部工具,以至于不得不重新发明轮子。

不少编辑器是围绕简单的【扁平】文档结构设计的,这使得表格、嵌入内容和字幕等内容难以理解,有时甚至无法实现。

Slate是一个可以高度定制化博众家之所长的富文本编辑器框架,其强大之处远不是本文所展现的这一点,你可以使用它来创建复杂且优雅的富文本编辑器,相对其他很多编辑器本身来说非常的灵活,文档也非常的详细,目前也正在不断地迭代当中,对富文本编辑器定制化需求比较高的可以尝试,希望能对你有所帮助!

又来了

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+wkwebview,支持加粗、下划线、斜体、对齐方式、字体更改颜色、插入图片、插入视频、插入链接、清除格式、撤回上一个操作

核心 :利用html5新特性contenteditable,当div的contenteditable为true时,div进入编辑状态,可以通过执行html5的命令对文本进行操作。命令文档地址:https://developer.mozilla.org/zh-TW/docs/Web/API/Document/execCommand。

具体实现 :

一:文件目录

1.editor.html,该文件实现了编辑器的节点骨架,一个contenteditable为true的div。

2.ZJSTextEditor.js,该文件是编辑器的核心内容,主要实现编辑器的各种操作,以插入视频为例,外部的wkwebview只需要执行js方法evaluateJavaScript:‘zss_editor.insertVideo(...)’,将url带入

3.EditorView这个文件主要是放wkwebview,以及wkwebview调用ZJSTextEditor.js中js方法的部分。如页面加载完,设置占位文字,或者默认对一些标签的处理

二:开发中产品提出的需求和我的设计方案

1.web端要求dom结构为<p>...</p> <p>...</p> <p>...</p> <p>...</p> <p>...</p>,也就是n个p里包含着你插入的视频图片等子节点?

我的方案:

1.1:在editor.html文件中插入的div中,插入一个默认的空p标签<p><br></p>,这样会保证你在文字中间插入图片、视频或者换行时,系统给你新增一个p标签包裹而不是div标签

1.2:在插入图片后加入一个空p,在文字中间插入视频后加入一个空的p和br再删除br,插入br是为了在文字中间插入视频时,让系统自动给你补全p标签,否则视频会被加在该文字的下一行。

2.每个图片要紧紧跟随一个图片输入框,且图片输入框支持粘贴,且图片和图片输入框可以通过某个按钮同时被删除?

我的方案:

图片有三个途径添加,第一个是粘贴来的新闻中带有图片,第二个是自己插入的图片,第三个是从html刚刚开始加载时自带图片(从web端发布的文章,在ios端编辑)。

2.1:每个图片要紧紧跟着一个图片输入框,我在三个途径处分别做了图片的处理,首先是自己插入的图片,我在插入图片时,紧接着插入一个textarea标签和一个p标签。插入一个p标签的目的是满足需求1,其次是粘贴来的新闻和html刚刚加载自带的图片,我选择遍历所有的图片标签,首先检查img标签的name属性是否有值,若没有值,新增textarea标签,并设置img标签和textarea标签的name属性为同一个UUID,若name属性有值,检查它的后一个兄弟节点是否跟随一个同name的dom,如果有且是i标签(提交数据时,要将所有的输入框变成i标签,此刻要从i标签变回输入框),将它转化成输入框,如果没有,添加默认输入框。

2.2:图片输入框支持粘贴,textarea自带粘贴

2.3:图片和图片输入框可以通过某个按钮同时被删除,设置img标签和textarea标签的name属性为同一个UUID,用name的原因是document.getElementsByName给的是该name的一组标签,删除时,只需要根据name删除即可

3.从微信或者头条粘贴过来的文章格式有误,文字偏大或者偏小?

我的解决方案:

由于拿不到原文章的js,所以只能在粘贴时去除标签内的所有内联样式。当然这个地方有个特殊情况要处理,比如用户在编辑时,设置了对齐方式,系统会自动给标签加上内联样式,这个样式我们不应该去掉。我的处理方案时自定义一个属性名zjs-style,在用户设置对齐方式时,将标签的style值赋值给zjs-style,我们在合适的时机,根据zjs-style复原其style

4.输入框在提交后变成不可输入的展示区域?

我的解决方案:

在提交时,遍历所有的textarea,若textarea没有值,去掉该textarea,若有值的话,将该textarea替换成i标签,且name值赋值给新的i。

5.从web端来的数据支持展示和再编辑?

我的解决方案:

在editor.html的div中加入默认占位文字<!-- defaultContent -->,在html资源加载前,将占位文字替换为后台给的html内容,并在网页加载完后,做相关处理

调试工具 :