前端富文本基本实现

lxf2023-03-15 18:22:01

前端富文本基本实现

什么是富文本

纯文本就是用纯文字编辑器编写,输入什么就是什么的文档,只包含字符。

富文本对应的是富文本格式(Rich Text Format),即 RTF 格式,又称多文本格式,是由微软公司开发的跨平台文档格式。除字符外还有丰富的样式。doc,docx,rtf,pdf 等都是富文本格式的文件类型。

前端富文本基本实现

富文本编辑器中的富文本,是由红色框中带有语义化标签和内联样式的 html 渲染实现的。通过富文本编辑器,即可实现富文本的编写、展示。

前端富文本基本实现

富文本输入模式实现

前端富文本编辑器首先要实现文本输入,一般常用两种方式实现。

iframe

在空白的 HTML 文档中嵌入一个 iframe,并将 designMode 属性设置为 on,文档就会变成可编辑的,实际编辑的则是 iframe 内的 body 元素。文档变成可编辑后,就可以像使用文字处理程序一样编辑文本。

前端富文本基本实现

前端富文本基本实现

元素设置 contenteditable

contenteditable 属性指定 HTML 文档中的元素。该方式是 IE 最早实现的。使用方式是在一个元素上添加 contenteditable 属性并设置为 true,然后该元素会立即被用户编辑。

前端富文本基本实现

前端富文本基本实现

两者特点

两种方式都可以实现编辑模式,并且这种编辑模式与 textarea 不同,其内部会用块级元素(默认为 div 元素)做换行处理,最终体现在 dom 结构中。

两者不同的是:iframe 方式可做到样式隔离,内部样式与外部样式不存在污染与冲突( tinymce 实现方式);元素设置 contentEditable 的方式( wangEditor 等实现方式)则和其他元素一样受到页面 css 作用。个人认为两者没有优劣之分,开发者根据自身需求选择即可。

富文件选区

富文本编辑中我们在进行编辑时首先会先选择一块文本区域(即选区),比如选择一段文字并进行字体加粗等操作,那么选区本身包含了哪些信息呢

Selection 对象表示用户选择的文本范围或插入符号的当前位置。它代表页面中的文本选区,可能横跨多个元素。文本选区由用户拖拽鼠标经过文字而产生。调用 window.getSelection()(developer.mozilla.org/zh-CN/docs/…) 可得到此对象,其内部常用属性如下:

anchorNode

返回选中区域对应的节点

anchorOffset

返回选中区域的起始下标,需要注意起始下标会根据左右方向选择的次序不同来展示不同的下标。如果 anchorNode 是字符串则对应文字下标,anchorNode 是元素,则对应选中区域对应它之前的同级节点的数目。

focusNode

返回选中区域终点所在的节点。

focusOffset

与 anchorOffset 类似,如果是 focusNode 是字符串,则对应最后一个选中的字符所在的位置,focusOffset 是元素,则对应选中区域对应同级节点的总数。

rangeCount

返回选中的区域所对应的连续的范围内的数量。

type

返回选中区域所对应的类别是连续 (Range),还是同一个位置的 (Caret)。

我们常通过 anchorNode 与 anchorOffset 属性判断选区起始位置,通过 focusNode 与 focusOffset 属性判断选区终止位置。

选区示例

window.getSelection()

用途

删除、替换选区内容&插入操作

Selection 对象有 deleteFromDocument,可以在编辑区域删除选区内容。如想删除后插入,可获取新的 Selection 对象,利用此时位置所在 dom 元素的方法插入对应的文字、元素。

富文本工具栏实现

bool = document.execCommand(aCommandName, aShowDefaultUI, aValueArgument)

调用execCommand()可以实现浏览器菜单的很多功能. 如保存文件,打开新文件,撤消、重做操作…等等. 有了这个方法,就可以很容易的实现网页中的文本编辑器.

  • aCommandName

  • 一个 DOMString ,命令的名称。可用命令列表请参阅 命令 。

  • aShowDefaultUI

  • 一个 Boolean,是否展示用户界面,一般为 false。Mozilla 没有实现。

  • aValueArgument

  • 一些命令(例如 insertImage)需要额外的参数(insertImage 需要提供插入 image 的 url),默认为 null。

<button onclick="bold()">粗体</button>
  <button onclick="italic()">斜体</button>
  <button onclick="changeColor()">改变颜色</button>
  <button onclick="insertImage()">插入图片</button>
  <button onclick="del()">删除</button>
  <button onclick="insert()">插入字符(表情)</button><br />

const bold = (val) => {
    document.execCommand('Bold', false, val)
  }
  const italic = (val) => {
    document.execCommand('italic', false, val)
  }
  const changeColor = (val = '#ff0000') => {
    document.execCommand('foreColor', false, val)
  }
  const insertImage = (val = 'https://s5.wandougongzhu.cn/s/a5/_6fb011.png') => {
    document.execCommand('insertImage', false, val)
  }
  const del = () => {
	document.execCommand("Delete", false, null);
  }

前端富文本基本实现