[开发总结]富文本前端框架对比分析
[排序不分先后,只是标记数量]
1. 如果你想直接引入,完全不定制,扔进项目就直接用
CKEditor
TinyMCE
Froala
Quill
Summernote(框架不太友善)
Trix
2. 想有非常高度的定制
可以看看 Slate.js,它基于 React.js。
用了 Slate.js 的知名产品有 Taskade,Taskade 的编辑器非常漂亮而且格式很多。
如果想开发和 Taskade 一样的编辑器,我觉得用如上里任何一个现成编辑器都是很难开发出来的(甚至不可能,因为要改动那么多还不如写个新的方便)就是得用 Slate.js。
而且 Slate.js 的官方 README 开头就花了不少篇幅来解释为什么又要开发一个新编辑器,提到了其他编辑器的不足,理由非常充分。
编辑器历史
一代编辑器
代表:UEditor、KindEditor、KissyEditor...等
二代编辑器
ProseMirror,Quill.js,Draft.js,Slatejs。比如Quill.js定义了一个叫dela的格式,专门描述文档和变化。
draftjs自定义了schema的方式,不过它的schema结构是扁平化的,这点上slatejs支持的更好,支持嵌套结构。
同时很多编辑器框架放弃了开箱即用,更多提供的是一个乐高积木,而不是已经拼好的玩具车。
三代编辑器
二代编辑器的使用者们发现,国际化和移动端并不能很好的处理。
所以最早的google doc在2010年就把contenteditable也放弃了,完全自己接管了光标。同样做了这种选择的还有iCloudPage,有道云笔记好像也是。这样子做代价很高,因为接手越多,意味着浏览器帮你做的越少。
这一代的我并没有做深入研究,因为他们并没有开源。我们其实也还没有到达这个阶段,没有足够的人力和精力去踩坑。
1. quill 富文本编辑器(初选,据说华为也在用)
l quill主要是大厂在用(华为,腾讯都在用),使用上和layUI很像,加上同事都有使用layUI的使用经验所以会很容易上手,页面很简约好看之前使用layUI的时候就感觉不像是在DOM对象,而是Delta,跟json数据很像,感觉就像是在配置项目而不是面向过程
- https://quilljs.com/guides/designing-the-delta-format/这是quill的delta的教程
- https://quilljs.com/docs/delta/
l blots & Parchment
Quill 里面有个 blots 的概念,想象一下,一段文字是一个段落,属于块状元素,该段落可以包含以下几种基础元素:
- 块状元素 (Block),例如标题;块状样式,例如行高,缩进,居中等;
- 纯文本内容 (Text),是个叶子结点;
- 内联元素 (Inline),例如等;内联样式,例如文字颜色,文字大小等;
- 非文本叶子结点 (Embed),例如图片,视频;
缺点:
1.中文文档很少,大部分都是英文文档
2.用到 MutationObserver,这表示对一些老式的浏览器会不支持。
3. Quill 的 Range 和 Selection 底层用的原生的 api,我们也知道原生的 Selection/Range 本来就比较坑,不然就不会有人自己实现一套 Selection 和 Range 了。
4. 内容管理平台中基于 Vue.js 开发,富文本编辑器使用的是 Quill。
而 Quill 简洁易用的优点,如今成了它的缺点 —— 它只保留特定的标签和样式,且没有可供修改的配置。
优点:
- 简单易上手
- 功能强大
- Quill 对现在很流行的 React、Vue或者 Angular 都能很好的支持
参考文献:
http://www.alloyteam.com/2017/09/13191/
description: 长相好看简约。基于它写插件也很简单,api 设计也很简单,api驱动设计
demo :https://quilljs.com/playground/#class-vs-inline-style
3.tinymce-vue
description : vue 官方package,功能丰富但是都是英文的
demo:https://github.com/tinymce/tinymce-vue
4. medium-editor
descripition: 更符合程序员的风格 ,purejs ,轻量只有28KB,兼容chrome firefox safari IE edge
demo :http://yabwe.github.io/medium-editor/
5. Squire
description: 开源 简约
demo:https://www.zoho.com/mail/
6.slate.js
优点
1. 插件是一等公民:插件是slatejs里面最重要的概念,以插件方式开放了一系列自定义的口子,甚至内核也是插件实现。插件的执行顺序依赖我们传入的插件列表的数组顺序。
2. 仿造dom:slate本身可以理解为一个model,一个仿dom的模型,我们的操作实际在与这个虚拟dom交互,交互完走react的setState渲染流程,设计天然运行效率高
3.使用react渲染:可能现在看来很平常的一点,其实抽象出model与view互通是编辑器开发的一次大进步。同时slatejs没有自建view层,而是拥抱了react
4.immutable:不可变,实现undo,redo的法门
5.schema以及normalize机制:非常优秀的机制,避免文档错乱的重要一环
6.源代码边界清晰:slate与slate-react负责的内容拆分清晰,下面会详细讲
7.浏览器兼容:slate-react处理了安卓,普通的浏览器兼容的坑(重要)
缺点
可高度定制化,但是碰到的问题超出能力范围
这个框架应该是否定了,随着深入理解发现,很多博客作者碰到的问题都是内核级别的bug,我根本应付不了。出于考虑,这个框架排在后面
总结
想有非常高度的定制,可以考虑,基于react.js
descripition : 插件化,简化API接口方面做出了自己的特色
作者描述:Why you choose slate?
Why create Slate? Well... (Beware: this sectionhas a few of my opinions!)
Before creating Slate, I tried a lot of theother rich text libraries out there—Draft.js, Prosemirror, Quill, etc. What Ifound was that while getting simple examples to work was easy enough, once youstarted trying to build something like Medium, Dropbox Paper or Google Docs,you ran into deeper issues...
The editor‘s "schema" washardcoded and hard to customize. Things like bold and italic were supported outof the box, but what about comments, or embeds, or even more domain-specificneeds?
Transforming the documents programmaticallywas very convoluted. Writing as a user may have worked, but making programmaticchanges, which is critical for building advanced behaviors, was needlesslycomplex.
Serializing to HTML, Markdown, etc. seemedlike an afterthought. Simple things like transforming a document to HTML orMarkdown involved writing lots of boilerplate code, for what seemed like verycommon use cases.
Re-inventing the view layer seemedinefficient and limiting. Most editors rolled their own views, instead of usingexisting technologies like React, so you have to learn a whole new system withnew "gotchas".
Collaborative editing wasn‘t designed forin advance. Often the editor‘s internal representation of data made itimpossible to use to for a realtime, collaborative editing use case without basicallyrewriting the editor.
The repositories were monolithic, not smalland reusable. The code bases for many of the editors often didn‘t expose theinternal tooling that could have been re-used by developers, leading to havingto reinvent the wheel.
Building complex, nested documents wasimpossible. Many editors were designed around simplistic "flat"documents, making things like tables, embeds and captions difficult to reason aboutand sometimes impossible.
Of course not every editor exhibits all ofthese issues, but if you‘ve tried using another editor you might have run intosimilar problems. To get around the limitations of their API‘s and achieve theuser experience you‘re after, you have to resort to very hacky things. And someexperiences are just plain impossible to achieve.
If that sounds familiar, you might likeSlate.
Which brings me to how Slate solves all ofthat...
opinions: 没找到插入图片 感觉跟markdown一样
7. draft.js
descripition : Draft.js除了与React紧密的整合之外,另外一个很大的优势就是利用contentEditable这个DOM特性解决一众编辑器小坑的同时,使用immutable的数据结构来代表编辑器的状态,很好的分离了DOM和state。所以除了Facebook,很多公司也上手了Draft.js,比如知乎。
Draft.js给富文本编辑器提供了一个很简单明了的解决办法,就是React -> view,immutable.js -> model,然后Draft.js提供编辑器操作作为controller,开源
8. Kindeditor
KindEditor 是一套开源的在线HTML编辑器,主要用于让用户在网站上获得所见即所得编辑效果,开发人员可以用 KindEditor 把传统的多行文本输入框(textarea)替换为可视化的富文本输入框。 KindEditor 使用 JavaScript 编写,可以无缝地与 Java、.NET、PHP、ASP 等程序集成,比较适合在 CMS、商城、论坛、博客、Wiki、电子邮件等互联网应用上使用
主要特点
快速:体积小,加载速度快
开源:开放源代码,高水平,高品质
底层:内置自定义 DOM 类库,精确操作 DOM
扩展:基于插件的设计,所有功能都是插件,可根据需求增减功能
风格:修改编辑器风格非常容易,只需修改一个 CSS 文件
兼容:支持大部分主流浏览器,比如 IE、Firefox、Safari、Chrome、Opera
初始化kindeditor编辑器
<script type="text/javascript"> var editor; KindEditor.ready(function(K) { editor = K.create(‘textarea[name="content"]‘, { allowFileManager : true }); }); </script>
提取kindeditor编辑器的内容
9.CKEditor5
好用是好用,但是界面相对优点老。但是也可以写出好看页面,插件很多很全。
Descriptiton: 能够继承继承vue,可以直接引入,可以 npm install,开源的,有收费内容
优点:易用性,全球化,可配置性和可定制性
现代化:基于ECS5和ES6编码,基于AMD和MVC模式,基于NPM分发。
多终端支持:支持桌面,平板,智能手机上的浏览器和app.
具有模块化体系结构的现代JavaScript RTF编辑器。它干净的用户界面和功能为创建语义内容提供了理想的所见即所得UX??。
- 用MVC架构,自定义数据模型,虚拟DOM编写在ES6中。
- 响应式图像和媒体嵌入(视频,tweet)。
- 自定义输出格式:HTML和Markdown支持。
- 通过自动格式化和协作来提高生产力。
- 通过设计可扩展和可定制
合作
使用CKEditor 5,每个应用程序都可以成为在线协作软件。通过更快的查看和即时交付来提高生产力。
- 实时协作编辑文档。
- 跟踪变化。
- 评论,讨论,带有化身的用户面板。
- 文本建议的仅注释模式。
- 支持所有富文本功能,包括表格或媒体。
图片上传
灵活的图像上传和文件管理器工具,用于向您的内容添加响应图像,视频或PDF文件。
- 一键式轻松拖放文件上传支持。
- 具有精细的用户权限的一流安全性。
- 文件和文件夹管理:上载,删除,移动,分类。
- 内置图像编辑器,可进行图像裁剪和调整大小或过滤器。
- 多种存储选项:本地文件服务器,FTP和云支持。
官网案例
链接:https://ckeditor.com/docs/ckeditor5/latest/examples/builds/classic-editor.html
<div name="content" id="editor"> <p></p> </div> <script type="text/javascript" src="../js/ckeditor/ckeditor.js"></script> <script> var data; ClassicEditor.create(document.querySelector(‘#editor‘), { ckfinder: { uploadUrl: ‘/‘ } } ).then(editor => { window.editor = editor; data = editor.getData(); console.log(data); } ) .catch(error => { console.log(error); } ); </script>
10.Tinymce
TinyMCE是一款易用、且功能强大的所见即所得的富文本编辑器
TinyMCE的优势:
- · 开源可商用,基于LGPL2.1
- · 插件丰富,自带插件基本涵盖日常所需功能(示例看下面的Demo-2)
- · 接口丰富,可扩展性强,有能力可以无限拓展功能
- · 界面好看,符合现代审美
- · 提供经典、内联、沉浸无干扰三种模式(详见“介绍与入门”)
- · 对标准支持优秀(自v5开始)
- · 多语言支持,官网可下载几十种语言。
- 官网及文档:www.tiny.cloud(右键)
- 官网下载:www.tiny.cloud/get-tiny/self-hosted/(右键)
- Github:github.com/tinymce(右键)
<html> <head> <meta charset="UTF-8"> <script type="text/javascript" src="../js/ckeditor/tinymce.min.js"> </script> <script type="text/javascript"> tinymce.init({ selector: ‘#myTextarea‘, width: 600, height: 300, plugins: [ ‘advlist autolink link image lists charmap print preview hr anchor pagebreak spellchecker‘, ‘searchreplace wordcount visualblocks visualchars code fullscreen insertdatetime media nonbreaking‘, ‘table emoticons template paste help‘ ], toolbar: ‘undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | ‘ + ‘bullist numlist outdent indent | link image | print preview media fullpage | ‘ + ‘forecolor backcolor emoticons | help‘, menu: { favs: {title: ‘My Favorites‘, items: ‘code visualaid | searchreplace | spellchecker | emoticons‘} }, menubar: ‘favs file edit view insert format tools table help‘, content_css: ‘css/content.css‘ }); </script> </head> <body> <textarea id="myTextarea"></textarea> </body> </html>