做過前端的朋友,大家或多或少都接到過做用戶互動的需求。這時候只要一聽到產品經理說能不能支持加粗,斜體和@好友,大家肯定就會在心里默念“S**t,又要跳富文本編輯器的坑了”。
曾經知乎上面有過一個問題,有多大比例的前端工程師,能在合理的時間內獨立開發出一個足以供商業網站使用的文本編輯器?大家一致認為在千分之一,甚至萬分之一左右。這樣我們要先了解富文本編輯器的各種特性(坑),才能往成為千分之一的道路前進。
富文本編輯器的坑在我總結起來有兩大類:
一是視圖層的繪制,Facebook早期是使用<div>在<textarea>上面實作效果,并且需要大量使用了DOM測量。早期Facebook工程師發愁的事情之一就是提及的藍色背景與文字偏離。

二是各種編輯時候的各種小(天)坑。比如游標位置,輸入法,兼容性。。。
面對上面的各種坑,一個傳統的解決辦法是使用DOM的特性,contentEditable。不過說到這很多同學要開始翻白眼了,雖然有很多不錯的實作(tinyMec,Quill),但是contentEditable還是有名的難易控制,并且在不同版本實作不同。
不過在React出現之后,事情有了轉機。作為一個視圖層庫,React能夠很好的抽象原生DOM的操作,讓開發者可以使用組件來定義不同的富文本格式。可以說一次性的降低了富文本編輯器的開發難度。
在React.js Conf 2016上面,Facebook開源了Draft.js,作為Facebook一眾文本編輯需求的產品上面的新選擇(狀態發布,評論,Facebook Note,Messenger)。

Draft.js除了與React緊密的整合之外,另外一個很大的優勢就是利用contentEditable這個DOM特性解決一眾編輯器小坑的同時,使用immutable的資料結構來代表編輯器的狀態,很好的分離了DOM和state。所以除了Facebook,很多公司也上手了Draft.js,比如知乎。
Draft.js給富文本編輯器提供了一個很簡單明了的解決辦法,就是React -> view,immutable.js -> model,然后Draft.js提供編輯器操作作為controller。讓我們來看下面一個例子:
import React from 'react';
import ReactDOM from 'react-dom';
import {Editor, EditorState} from 'draft-js';
class MyEditor extends React.Component {
constructor(props) {
super(props);
this.state = {editorState: EditorState.createEmpty()};
this.onChange = (editorState) => this.setState({editorState});
}
render() {
return (
<Editor editorState={this.state.editorState} onChange={this.onChange} />
);
}
}
ReactDOM.render(
<MyEditor />,
document.getElementById('container')
);
editorState可以理解為編輯器在某一刻的一個快照(snapshot)。同時editorState也是一個由不可變(immutable)資料型別構成的物件。依據editorState,我們可以實作對編輯器內容的嚴格控制,并且知道如何render編輯器界面。
而富文本功能的實作,既可以通過已有的html element(h1,h2,ul,ol)也可以通過自定義的CSS。
.superFancyBlockquote {
color: #999;
font-family: 'Hoefler Text', Georgia, serif;
font-style: italic;
text-align: center;
}
編輯器的操作則是非常的函式式化,之前我提到過,每個editorState可以看做編輯器的一個快照。這樣每個操作(加粗,洗掉等)輸入引數為editorState,回傳結果也是一個editorState,再由DOM去render。這樣狀態機的設計,既函式式化,又可以保證將編輯器操作流水線化。比如切換code模塊的介面就是:
toggleCode: (editorState: EditorState) => EditorState
除了Draft.js,現在開源社區還有一個類似的很火的開源富文本編輯庫 - Slate。

Slate除了沿用很多Draft.js的先進的想法之外,更是在插件化,簡化API介面方面做出了自己的特色。現在Gitbook和語雀都使用了Slate作為底層編輯器,而且前幾天在Hacker News上面出現以后更是star數目一躍到了12000+(迫近Draft.js)。Slate官方介紹自己的優勢有:
* 插件是一等公民
* 檔案格式不設限
* 層級檔案模型
* 與DOM平行
* 無狀態的視圖層與不可變的資料層
* 直觀的操作
* 可協調的資料模型
* 明確的核心邏輯
之前在舊金山跟Slate創始人Ian面基的時候,他也分享過自己開發富文本編輯器遇到過得各種坑和各種思考,并且希望把Slate做成一個完全插件化的編輯器框架。(p.s.,不過作為個人開發者,Ian小哥的任性,比如對IME和協同的支持的抉擇程序,也非常有意思)。
Slate的代碼模塊化程度非常高,設計也力求插件化優先。小哥作為Rhode Island School of Design畢業,設計師轉的程式員,對介面設計的追求可見一斑(沒事改API介面名稱的習慣就不吐槽了)。
如果大家感興趣,我也計劃陸續推出幾篇解讀這個框架原始碼的文章。
在研究了這么多富文本編輯器,WYSIWYG編輯器之后,我和我的好基友也開發了一款專為程式員而生的筆記應用 - Tea:

現在已經開始內測啦,對我們感興趣的同學可以去我們在掘金上的文章(https://juejin.im/post/5bffadf3f265da616a476096),里面有我們專案更詳細的介紹和內測版下載鏈接。
uj5u.com熱心網友回復:
weww
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/129027.html
標籤:非技術區
上一篇:DW里如何把html轉換成Asp
