1
头图

概述

在线富文本编辑器是用于在 Web 浏览器中编辑文本的界面,它为用户呈现所见即所得(WYSIWYG)的编辑区域。它的优势是充分利用 HTML 的丰富表现能力,减少用户对文本格式转换的工作量。这里的富文本是相较于纯文本而言,与纯文本不同的是它具有样式、排版等信息。

工作原理

在线富文本编辑器是如何工作的呢?语雀团队的一位研发工程师总结的很好,即在线富文本编辑器主要解决两个问题:

  1. 如何在浏览器呈现富文本。
  2. 如何在浏览器编辑富文本。

对于问题 1,既然在线富文本是运行在浏览器中,那肯定是浏览器支持的呈现方式。目前市面上主流的方案都是采用 HTML 标签结合 CSS 样式来呈现富文本,另外的一些富文本编辑器也会采用 Canvas 来呈现富文本, 比如 Google Docs。

对于问题 2,也就是如何在网页进行文字的输入和编辑。回忆我们平时的网页浏览,绝大部分情况是在有表单元素的情况下才可进行用户输入, 例如我们经常用的百度搜索,那就是一个 input 框供用户输入想要检索的关键字。诸如 input、textarea 之类的表单元素虽然允许用户进行文字输入,但是它们只能输入纯文本内容,而我们要实现的却是一个富文本编辑器。好在浏览器为绝大多数 HTML 元素提供了一个 contenteditable 属性,该属性可以用来控制元素是否可以编辑。在浏览器地址栏输入如下地址并访问,那整个网页就是一个可输入文本的编辑器:

因为现代浏览器几乎都支持该属性,而且该属性又可以利用浏览器提供的一些默认行为,因此利用该属性实现富文本编辑器是绝大多数开发者的不二选择。

但凡事都有例外,一些实力比较强大、以富文本编辑器为主营业务的团队也会采用模拟光标加事件拦截来实现富文本编辑器。我们不妨思考一下,平时浏览网页的时候,如何判断一个网页是否可以编辑的呢?概括来说就是该区域光标是可以聚焦的,且用户通过键盘等设备输入字符的时候输入的字符能呈现在该区域。正如一句俗语所说,如果走起来像一只鸭子、叫起来像一只鸭子,那么它就是一只鸭子。如果我们能让网页的一块区域可以鼠标聚焦,且允许用户输入字符在上面,那么它就可以称之为富文本编辑器。

以 Google Docs 为例,当你用鼠标点击文档区域,会出现一个闪动的光标。当用浏览器开发者工具查看页面元素的时候,你会发现文档编辑区域既不是可输入的 input 等表单元素,又没有上文提到的 contenteditabe 属性,那么为什么光标可以在该区域聚焦并且显示字符的呢?原来你所看见的光标,只不过是用 HTML 加 CSS 实现的虚拟光标。当你用鼠标点击文档区域的时候,页面会拦截点击事件,并计算光标的位置,实时地绘制出一条虚拟的光标。当你输入文字的时候,同样是通过拦截的输入事件获取用户输入的字符,实时地显示在文档编辑区域。用户对这一切是无感知的,就好像真的是在一个可输入、编辑的区域进行文字创作。

优劣对比

以 contenteditalbe 属性实现富文本编辑功能,并用 HTML 加 CSS 展示富文本内容的这类编辑器:

优点:开箱即用,给元素加上一个属性就可以开始编辑、输入,另外浏览器提供了一些默认的行为,比如光标聚焦、选取高亮。

缺点:缺少一致性,这包括内容一致性和表现一致性。内容一致性表现为,当编辑器里的内容看起来一样,但实际上存储的 HTML 结构不一致。比如当你在编辑框按下回车,是增加一个 div 标签 还是 p 标签,亦或是 <br/> 标签,这在不同浏览器中可能发生不同的行为。表现一致性表现为,当存储的 HTML 结构一致,在不同的浏览器的显示样式也会有不同,比如同一个 button 标签在不同浏览器中外观样式也会不一样。前 Medium 工程师曾经发表一篇名为 “Why ContentEditable is Terrible”的文章,对这方面感兴趣的可以搜索这篇文章阅读了解。

自己实现模拟光标拦截用户输入,并用 Canvas 来展示富文本内容的这类编辑器:

优点:高一致性以及性能提升。Canvas 只是一块画布,本身并没有任何内容,我们可以通过 JavaScript 在画布上绘制图像、文字,因此它能够做到在不同浏览器中表现一致。另外在编辑超大文档的时候,对文档的修改容易触发浏览器的重绘、回流,这些都会导致性能问题,而使用了 Canvas 后开发者则有了更大的优化空间。

缺点:复杂度高。鼠标聚焦、选区等操作都要自己实现。举例来说,你把光标移动到单词开头,然后拖动选取到单词结尾,这个单词就会高亮。在你看来这是理所当然,这是因为浏览器帮我们做了这些操作。如果是自己拦截用户操作并用 Canvas 绘制,那么这一切都要自己去实现,甚至用户单击鼠标你都要判断用户是在单击还是在拖选。另外通过 Canvas 绘制的富文本,是 SEO 不友好的,因为你的内容都是绘制在画布内,搜索引擎无法感知。同理,这对于有视觉障碍的用户,也会带来使用上的麻烦。

本文首发于个人公众号,点击阅读原文


Zuckjet
437 声望657 粉丝

学如逆水行舟,不进则退。