一个Level 0富文本编辑器的进化历程

news2025/1/18 4:42:44

本文作者为 360 奇舞团前端开发工程师

一个Level 0富文本编辑器的进化历程

富文本编辑器是我们在生活中常用到的编辑工具,本文将为大家介绍富文本编辑器技术成长的历程,在最后会带大家利用document.execCommand实现一个简单的传统编辑器。

ps:document.execCommand 是实现富文本编辑器的核心 API 。但遗憾的是 document.execCommand 已经被 MDN 给废弃了。而且,一直以来,各个浏览器对于它的实现,细节上也没有完全统一,浏览器兼容性一直比较头疼。本文仅作富文本编辑器的简单探究。

编辑器技术阶段划分

通常大家把编辑器技术分为三个阶段

Level 0 第一阶段,是编辑器的起始阶段,代表旧一代的编辑器的实现

主要依赖于浏览器原生的编辑能力,用户内容的输入是浏览器直接处理,加粗、斜体、回车等这类的处理则是捕获浏览器的事件来覆盖浏览器默认行为来实现,再辅以一些DOM的嵌套规则和复杂数据输入(如粘贴)的过滤规则来约束数据的正确性,这类编辑器整体思路还是比较清晰的。

虽然基于浏览器原生编辑能力,输入非常流畅,但是不可以预测的交互,容易出现数据混乱(拖拽、复制粘贴、删除)。相同操作不同浏览器可能有不同的实现(比如基本的加粗、斜体、Enter),很难实现表现和数据完全统一。

Level 1 第二阶段,是在第一阶段发展过来的,有一定的先进性,也引入了主流的一些编程思想,对于富文本内容有一定的抽象

这个时期的富文本编辑器的底层还是依赖原生DOM的contentEditable特性,但是他们对DOM Tree以及数据的修改操作进行了抽象,抽象出了数据变化的操作。这意味着编辑器开发者大部分场景下其实不是直接通过修改DOM完成编辑器功能的,他们通过捕获用户的操作行为,将原有的修改dom调整为操作API修改数据模型,再将更新后的状态映射至视图,来实现编辑器的所见即所得的效果。输出数据可以是HTML的字符串,也可能是自己嵌套的文档模型(JSON)。

Level 2 第三阶段,完全不依赖浏览器的编辑能力,独立的实现光标和排版

早在2010年Google Doc就使用了全新的技术来实现富文本编辑器,实现了自己的富文本编辑 API ,就是大家通常说的第三阶段(Level 2),不使用Contenteditable,可以实现文本的独立排版,不再依靠浏览器的任何编辑功能,自主实现选区光标和内容排版,只不过目前还没有一款基于这套架构的开源技术。

从Level 0到Level 2,个人理解就是将富文本编辑器的控制权一步步由浏览器控制,变成由开发者控制者。

具体实现一个传统的简单编辑器

传统的富文本编辑器中内容的可编辑主要依赖DOM的contentEditable属性,基于原生execCommand或者自定义扩展的execCommand去操作DOM实现富文内容的修改。

当一个HTML文档切换到设计模式(designMode)时,文档对象暴露 execCommand方法,该方法允许运行命令来操纵可编辑区域的内容。大多数命令影响文档的选择(粗体,斜体等),而其他命令插入新元素(添加链接)或影响整行(缩进)。当使用 contentEditable时,调用 execCommand() 将影响当前活动的可编辑元素。

要实现富文本编辑器需要了解哪些API
contenteditable 属性:该属性用于使元素可编辑。通过将其设置为"true",可以使元素具备编辑功能。  

innerHTML 属性:这个属性用于获取或设置元素的 HTML 内容。通过读取或修改该属性,可以获取或更改编辑区域的内容。   

execCommand() 方法:这个方法用于执行命令,比如设置字体样式、插入链接、插入图像等。使用该方法可以通过命令名称来执行编辑操作。
语法:execCommand(aCommandName, aShowDefaultUI, aValueArgument)
参数:
aCommandName:指定要执行的命令名称的字符串。
aShowDefaultUI:一个布尔值,指示是否应显示默认用户界面。Mozilla 中未实现此功能。
aValueArgument:对于需要输入参数的命令,是提供该信息的字符串。例如,insertImage需要插入图像的 URL。指定null是否不需要参数。
例如:通过执行document.execCommand('bold'),可以将选定的文本设置为粗体.

Selection 对象:Selection 对象表示用户当前选择的文本范围,可以使用 Selection 对象获取光标位置、选择范围以及进行文本插入、删除等操作。

Range 对象:Range 对象表示文档中的一个范围区域,可以用于精确地控制选定的文本范围。它提供了一系列的方法和属性,可以进行文本选取、插入、删除等操作。
创建编辑区域

首先需要一个编辑区域,创建一个div元素,元素设置contenteditable=true

<!-- HTML -->
<div id="editor" contenteditable="true" style="border: 1px solid #ccc; min-height: 200px;"></div>
创建一个编辑器控制栏

编辑器控制栏,用于对文本进行各种控制修改,我们就写一个最简单的,设置字体倾斜。上面有介绍,在 JavaScript 中,我们可以使用 document.execCommand() 方法来设置文本样式。

<!-- HTML -->
 <select id="fontStyle">
    <option value="normal">Normal</option>
    <option value="bold">Bold</option>
    <option value="italic">Italic</option>
  </select>
  <button onclick="setFontStyle()">Set Style</button>

<!--  JS -->
function setFontStyle() {
  const fontStyle = document.getElementById('fontStyle').value;
  document.execCommand(fontStyle, false, null);
}
内容输出

保存的内容主要是通过innerHTML拿到。

function saveContent() {
  const editor = document.getElementById('editor');
  const content = editor.innerHTML;
  console.log(content); // 输出富文本内容是HTML字符串
}

以上就实现了一个特别简单基础的富文本编辑器。

结语

目前,有很多针对富文本编辑器的一些基本功能和拓展封装成一个开源的富文本编辑器,比如最开始百度的Ueditor,比较流行的Quill、Slate,基本都是实现了自己的contentEditable,抛弃了对浏览器原生的contentEditable特性的依赖。在我们平时开发过程中,对于一些简单的编辑功能,可以直接使用这些开源富文本编辑器的基础API,并且在此基础再做扩展。

参考文章

https://pubuzhixing.medium.com/the-evolution-of-open-source-rich-text-editor-technology-1ced33a9219d

https://juejin.cn/post/7240751116702122021?searchId=2024040916251168B31605126F7D0F8C44

- END -

关于奇舞团

奇舞团是 360 集团最大的大前端团队,代表集团参与 W3C 和 ECMA 会员(TC39)工作。奇舞团非常重视人才培养,有工程师、讲师、翻译官、业务接口人、团队 Leader 等多种发展方向供员工选择,并辅以提供相应的技术力、专业力、通用力、领导力等培训课程。奇舞团以开放和求贤的心态欢迎各种优秀人才关注和加入奇舞团。

067f77037af2c450927fe0d880b6f78b.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1622799.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

EasyCVR视频汇聚平台无法自动播放视频的原因排查与解决

国标GB28181协议EasyCVR安防视频监控平台可以提供实时远程视频监控、视频录像、录像回放与存储、告警、语音对讲、云台控制、平台级联、磁盘阵列存储、视频集中存储、云存储等丰富的视频能力&#xff0c;平台支持7*24小时实时高清视频监控&#xff0c;能同时播放多路监控视频流…

contenteditable可编辑功能,监听输入内容与回车操作

contenteditable 在div元素上添加contenteditable"true" 可以让div变成可编辑元素 <div class"word-block" contenteditable"true"></div>同时还支持回车换行 回车后就会生成一个div元素 添加 -webkit-user-modify: read-write-p…

spring DisposableBean作用,在spring Bean销毁时的钩子 以及@PreDestroy

DisposableBean 作用 在Spring框架中&#xff0c;DisposableBean是一个接口&#xff0c;它定义了一个单一的方法&#xff0c;用于在Spring容器关闭时或一个由Spring管理的Bean不再需要时执行特定的清理操作。当一个Bean实现了DisposableBean接口&#xff0c;Spring容器会在销毁…

VTC视频时序控制器原理以及Verilog实现

文章目录 一、前言二、视频时序控制原理三、Verilog实现3.1 代码3.2 仿真以及分析 一、前言 VTC&#xff08;Video Timing Controller&#xff09;是一种用于产生视频时序的控制器&#xff0c;在图像领域经常会输出各种分辨率和帧率的视频格式。因此为了方便&#xff0c;设置一…

C++: IO流

目录 1、C语言输入输出 流的概念&#xff1a; 2、CIO流 3、C文件IO流 1、C语言输入输出 C语言中我们用到的最频繁的输入输出方式就是scanf () 与 printf() 。 scanf(): 从标准输入设备 ( 键 盘 ) 读取数据&#xff0c;并将值存放在变量中 。 printf(): 将指定的文…

C语言入门课程学习笔记2

C语言入门课程学习笔记2 第8课 - 四则运算与关系运算第9课 - 逻辑运算与位运算第10课 - 深度剖析位运算第11课 - 程序中的选择结构 本文学习自狄泰软件学院 唐佐林老师的 C语言入门课程&#xff0c;图片全部来源于课程PPT&#xff0c;仅用于个人学习记录 第8课 - 四则运算与关系…

pycharm安装AI写代码插件

在IDE安装特慢&#xff08;可能找不到插件&#xff09; 去官网搜一下 对应安装包 下载zip在IDE解压 插件--已安装齿轮图标--从磁盘里安装 选择下载的插件 应用 --重启OK

在ubuntu上安装mysql(在线安装需要)

安装环境 虚拟机系统&#xff1a; Ubuntu 打开虚拟机 安装步骤 (1) 安装 将系统中的所有软件包都升为最新版本 sudo apt update 安装 MySQL sudo apt install mysql-server查询 MySQL 版本 mysql --version(2) MySQL 安全设置 进入 MySQL Shell sudo mysql设置 …

window平台C#实现软件升级功能(控制台)

window平台C#实现软件升级功能 之前用window窗体实现过一个升级功能&#xff0c;后来发现多个项目都需要升级功能&#xff0c;现改成可接收参数实现一种通用的exe.改用控制台方式实现这个升级功能&#xff0c;这样不仅实现了接收参数&#xff0c;升级程序体积也比原来的窗体形式…

java自动生成pojo,springboot自动生成pojo

第一步 pom引入依赖 <dependencies><!-- mybatis-generator --><dependency><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-core</artifactId><version>1.3.7</version></dependency>&…

开源电商小程序源码+搭建 支持全平台端口+商家自营+多商户入驻 带分销功能 可自用DIY界面

开源电商小程序源码系统为商家提供了一个快速搭建和部署电商平台的解决方案。商家可以利用该系统&#xff0c;在较短的时间内构建出功能齐全、界面美观的电商小程序&#xff0c;无需从零开始编写代码&#xff0c;从而大大节省了开发成本和时间。 分享一个开源电商小程序源码系…

OpenUI在windows下部署使用

OpenUI OpenUI是一个基于Python的AI对话平台&#xff0c;支持接入多种AI模型。 通过聊天的方式来进行UI设计&#xff0c;你可以通过文字来描述你想要的UI界面&#xff0c;OpenUI可以帮你实时进行渲染出效果 安装OpenUI 这里预设你的电脑上已安装git、Python和pip&#xff0…

Nginx 搭建Web服务

题目&#xff1a; 1.web服务器的主机ip&#xff1a;192.168.78.128 2.web服务器的默认访问目录为/var/www/html 默认发布内容为default‘s page 3.站点news.timinglee.org默认发布目录 为/var/www/virtual/timinglee.org/news 默认发布内容为 news.timinglee.org 4.站点login.t…

Power BI 如何解决月份排序错误/乱序问题(自定义顺序/正确排序)

问题描述 在创建图标时&#xff0c;月份标签没有按照正确的顺序排列。 解决方案&#xff1a; Sort by Column 单击选中排序错误的列&#xff08;MMM&#xff09;根据列排序 (sort by Column)选择需要根据哪一列排序。 这里选择的是Month列&#xff0c;这一列有月份的序号1-…

如何通过香港站群服务器提升跨境电商交易效率?

如何通过香港站群服务器提升跨境电商交易效率? 在全球电子商务迅速发展的今天&#xff0c;跨境电商已成为企业拓展国际市场、获取更多商机的重要途径。然而&#xff0c;跨境电商面临的挑战也不容小觑&#xff0c;尤其是在交易效率方面。利用香港站群服务器&#xff0c;不仅可…

做抖音小店如何选品?这几个技巧,精准“锁定”爆品!

哈喽~我是电商月月 做抖音小店最重要的就是选品&#xff0c;这点大家都知道 一个店铺商品选的好&#xff0c;顾客喜欢&#xff0c;质量完好&#xff0c;销量和售后都不用操心&#xff0c;和达人合作时&#xff0c;爆单的机会也就越高 那这种商品是什么样的&#xff0c;新手开…

快速了解-BTP

名词了解 BTP&#xff1a;SAP Business Technology Platform 是一个技术和业务的平台ETWEAVER &#xff08;SAP NW&#xff09;&#xff1a;NetWeaver本质上是SAP一系列技术产品的集成平台PAAS Cloud Foundry&#xff08;云原生&#xff09;&#xff1a;开源云服务平台烟囱式…

通配符/泛域名证书的五大优势

在数字化时代&#xff0c;网络安全成为企业及个人关注的焦点。为了确保在线信息传输的安全性与私密性&#xff0c;SSL/TLS证书成为网站加密通信的重要工具。其中&#xff0c;通配符证书作为一种特殊类型的SSL证书&#xff0c;以其独特的优势在众多证书类型中脱颖而出&#xff0…

Python程序设计教案

文章目录&#xff1a; 一&#xff1a;软件环境安装 第一个软件&#xff1a;pycharm 第二个软件&#xff1a;thonny 第三个软件&#xff1a;IDIE&#xff08;自带的集成开发环境&#xff09; 二&#xff1a;相关 1.规范 2.关键字 3.Ascll码表 三&#xff1a;语法基础…

LeetCode-2007. 从双倍数组中还原原数组【贪心 数组 哈希表 排序】

LeetCode-2007. 从双倍数组中还原原数组【贪心 数组 哈希表 排序】 题目描述&#xff1a;解题思路一&#xff1a;排序 哈希表解题思路二&#xff1a;排序 队列解题思路三&#xff1a;消消乐 题目描述&#xff1a; 一个整数数组 original 可以转变成一个 双倍 数组 changed &…