主要知识点:contentEditable 以及 document.execCommand

日常使用的输入框,大多直接使用input,支持正常的文本操作,但是想要做复杂的内容输入,就需要一个富文本编辑器,所以我就查找资料,开始了一段富文本编辑器的探索之旅。

首先使用的是DOM元素的contentEditable属性,该属性可以将DOM元素改为可编辑状态,也就是点击后可以出现光标,每次点击回车键,都会重新添加一个div节点。利用div可包万物的特性,所以可以通过它来开发一款富文本编辑器。

重点来了,div输入也只能输入正常的文本,如果想加粗,斜体,插入图片,超链接,该怎么办?这就需要用到document.execCommand了,但是这是一个被官方弃用(不再推荐使用)的特性。

当一个 HTML 文档切换到设计模式时,document 暴露 execCommand方法,该方法允许运行命令来操纵可编辑内容区域的元素。

大多数命令影响document的 selection(粗体,斜体等),当其他命令插入新元素(添加链接)或影响整行(缩进)。当使用contentEditable时,调用 execCommand() 将影响当前活动的可编辑元素。

/**
* 语法:
* @param{string} aCommandName 命令的名称
* @param{boolean} aShowDefaultUI 是否展示用户界面
* @param{} aValueArgument 一些命令(例如 insertImage)需要额外的参数(insertImage 需要提供插入 image 的 url),默认为 null。
*/
var bool = document.execCommand(aCommandName, aShowDefaultUI, aValueArgument);
// 如果执行成功,则返回true,反之,返回false

execCommand可使用的commandName有以下几种:

命令 含义 示例
backColor 修改文档的背景颜色。在 styleWithCss 模式下,则只影响容器元素的背景颜色。这需要一个<color> 类型的字符串值作为参数传入。注意,IE 浏览器用这个设置文字的背景颜色。 document.execCommand(“backColor”, false, “#FF0000”)
bold 开启或关闭选中文字或插入点的粗体字效果。IE 浏览器使用 <strong>标签,而不是<b>标签。
copy 拷贝当前选中内容到剪贴板。启用这个功能的条件因浏览器不同而不同,而且不同时期,其启用条件也不尽相同。使用之前请检查浏览器兼容表,以确定是否可用。
createLink 为选中内容创建超链接,需要一个hrefURI 字符串作为参数值传入。URI 必须包含至少一个字符,例如一个空格。 document.execCommand(“createLink”, false, “https://baidu.com”)
cut 剪贴当前选中的文字并复制到剪贴板。启用这个功能的条件因浏览器不同而不同,而且不同时期,其启用条件也不尽相同。使用之前请检查浏览器兼容表,以确定是否可用。
fontName 在插入点或者选中文字部分修改字体名称。需要提供一个字体名称字符串 (例如:“Arial”) 作为参数。
fontSize 在插入点或者选中文字部分修改字体大小。需要提供一个 HTML 字体尺寸 (1-7) 作为参数。
foreColor 在插入点或者选中文字部分修改字体颜色。需要提供一个颜色值字符串作为参数。
heading 添加一个标题标签在光标处或者所选文字上。需要提供标签名称字符串作为参数(例如:“H1”、“H6”)(IE 和 Safari 不支持) document.execCommand(“heading”, false, “H1”)
insertImage 在插入点插入一张图片(删除选中的部分)。需要一个 URL 字符串作为参数。这个 URL 图片地址至少包含一个字符。空白字符也可以(IE 会创建一个链接其值为 null)
insertOrderedList 在插入点或者选中文字上创建一个有序列表
insertUnorderedList 在插入点或者选中文字上创建一个无序列表。
italic 在光标插入点开启或关闭斜体字。
justifyCenter 对光标插入位置或者所选内容进行文字居中
justifyFull 对光标插入位置或者所选内容进行文本对齐。
justifyLeft 对光标插入位置或者所选内容进行左对齐。
justifyRight 对光标插入位置或者所选内容进行右对齐。
outdent 对光标插入行或者所选行内容减少缩进量。
redo 重做被撤销的操作。
undo 撤销最近执行的命令。
underline 在光标插入点开启或关闭下划线。
unlink 去除所选的锚链接的<a>标签
formatBlock 添加一个 HTML 块式标签在包含当前选择的行,如果已经存在了,更换包含该行的块元素 (在 Firefox 中,BLOCKQUOTE 是一个例外 -它将包含任何包含块元素). 需要提供一个标签名称字符串作为参数。几乎所有的块样式标签都可以使用 (例如。“H1”, “P”, “DL”, “BLOCKQUOTE”). (IE 浏览器仅仅支持标题标签 H1 - H6, ADDRESS,和 PRE,使用时还必须包含标签分隔符 < >, 例如 “<H1>”.) document.execCommand(“formatBlock”, false, “H1”)
enableObjectResizing 启用或禁用图像和其他对象的大小可调整大小手柄。(IE 浏览器不支持)
enableInlineTableEditing 启用或禁用表格行和列插入和删除控件。(IE 浏览器不支持)
enableAbsolutePositionEditor 启用或禁用允许移动绝对定位元素的抓取器。Firefox 63 Beta/Dev Edition 默认禁用此功能

formatBlock是一个自定义的命令,可以通过输入指定的标签名,进行创建标签并包裹选中内容。例如这种:document.execCommand(“formatBlock”, false, “H1”),就可以创建一个H1标签,与 document.execCommand(“heading”, false, “H1”) 效果相同


这是我创建的富文本效果图,使用了react+antd

工具箱设置为:

const exec = (commandName, value = null) => {var a = document.execCommand(commandName, false, value);console.log(a, commandName, value);
};const tools = [{key: 'bold',icon: <b>B</b>,title: '加粗',},{key: 'italic',icon: <i>I</i>,title: '斜体',},{key: 'underline',icon: <u>U</u>,title: '下划线',},{key: 'justifyLeft',icon: <AlignLeftOutlined />,title: '左对齐',},{key: 'justifyCenter',icon: <AlignCenterOutlined />,title: '居中对齐',},{key: 'justifyRight',icon: <AlignRightOutlined />,title: '右对齐',},{key: 'insertOrderedList',icon: <OrderedListOutlined />,title: '有序列表',},{key: 'insertUnorderedList',icon: <UnorderedListOutlined />,title: '无序列表',},{key: 'createLink',icon: <LinkOutlined />,title: '超链接',onClick() {setModalType('createLink');},},{key: 'formatBlock',icon: 'H',title: '标题',mode: 'hover',hoverDom: (<ul>{[1, 2, 3, 4, 5, 6].map((item) => (<li>{/* <a href="javascript:;" onClick={() => exec('formatBlock', 'H1')}> */}<Button onClick={() => exec('formatBlock', 'H1')}>H{item}</Button>{/* </a> */}</li>))}</ul>),},
]

期间有个问题,创建标签工具时,怎么都无法给选中内容添加H1标签,但是单独给button使用document.execCommand(“heading”, false, “H1”)是可以的,说明了Button可以,div不可以。之后又尝试了一下a标签,如果不加href=“javascript:;”,也不能正常添加,加上后就可以正常添加了。
由此可见,document.execCommand命令不能在 普通文本的节点上使用(该节点不能被选中文本),否则点击文本时,浏览器会认为你开始了新的选择文本动作,导致之前的选中区域失效,此时再去添加H1标签,就会导致选中区域是空的,从而导致不生效。

有兴趣的可以自己尝试一下。感谢您的阅读,有问题可以留言,或者私信。

记录React之富文本编辑器相关推荐

  1. 【重点突破】—— React实现富文本编辑器

    前言:富文本编辑器Rich Text Editor, 简称 RTE, 是一种可内嵌于浏览器,所见即所得的文本编辑器.   一.安装插件 react-draft-wysiwyg: 文本编辑器插件 dra ...

  2. 基于React的富文本编辑器——Braft Editor使用

    antd 是基于 Ant Design 设计规范实现的 高质量 React 组件库,倾向于只提供符合该规范且带有视觉展现的 UI 组件,也尽量不重复造轮子. 如果要在React项目中使用富文本编辑器, ...

  3. 2021 年 React 的 5 大富文本编辑器

    5大富文本编辑器 今天,富文本编辑器被用于许多应用中,包括简单的博客和复杂的内容管理系统.然而,选择一个并不容易,因为有很多具有不同功能的编辑器. 因此,在这篇文章中,我将评估5个React的富文本编 ...

  4. 【推荐】1657- 灵活可扩展,2023年值得尝试的13款富文本编辑器

    作为前端开发人员,我们经常需要为网站和应用程序添加文本内容.与传统的文本编辑器不同,富文本编辑器可让您轻松创建各种类型的文本内容,包括加粗字体.斜体字.框架.列表.图片和视频等. 本文我将向大家推荐 ...

  5. layui后台管理、图片裁切、cropper富文本编辑器实现

    需求:后台管理系统一般都会有图文混排功能(比如新闻应用,电商商品详情),这个一般使用富文本编辑器来实现:还有一个就是图片的裁切(比如用户的头像,比如博客的封面),因为在开发这两个功能的时候,也遇到了很 ...

  6. 灵活可扩展,2023年值得尝试的13款富文本编辑器

    作为前端开发人员,我们经常需要为网站和应用程序添加文本内容.与传统的文本编辑器不同,富文本编辑器可让您轻松创建各种类型的文本内容,包括加粗字体.斜体字.框架.列表.图片和视频等. 本文我将向大家推荐 ...

  7. React H5 使用div自定义简单富文本编辑器

    最近项目中h5端要实现图文上传,而且还要支持用户用户输入的格式,例如换行啥的,那么使用输入控件保存输入内容,图片上传控件就不合适了,因为很难知道用户的输入样式. 如果使用一些现有的富文本编辑器,貌似又 ...

  8. React 版本的真开箱即用的富文本编辑器wysiwyg

    React 版本的真开箱即用的富文本编辑器 这篇文章推荐的react 版的富文本编辑器名字叫做wysiwyg,第一时间你可能觉得这个名字起的很烂,很难记,但是当你知道它的全称后就很好记了,全称为 Wh ...

  9. uniapp 微信小程序 editor富文本编辑器 api 使用记录

    文章目录 1.查看官方示例 2.关于富文本编辑器的工具栏 3.自己实践一下 效果 这里记录一下自己研究学习的结果 之前一直使用textarea 来进行内容的编辑.但是局限性还是太多,最近发现了edit ...

最新文章

  1. websphere内存溢出
  2. 【学术相关】博士新生应该懂得哪些道理?
  3. 周鸿祎的“加法”和“减法”
  4. 7z apache解析漏洞_解析漏洞(Web漏洞及防御)
  5. 延迟或计划邮件的发送(zz.is2120)
  6. c++中内敛函数_C/C++求职者必备 23 道面试题,一道试题一份信心
  7. php 转换数组为小写,PHP如何将数组键转换为小写?
  8. 252.Meeting Rooms
  9. 解题报告 B_station
  10. 斯特林公式--求n!的位数
  11. VS2019配置opencv4.1.2(永久配置)
  12. 抖抖.....抖个不停的伺服电机——转动惯量匹配技术及资料分享
  13. 微信公众号 网页授权登入
  14. (15.1.16)项目管理简述
  15. java公交路线查询微信小程序源码
  16. 【NLP】千呼万唤始出来——GPT-3终于开源!
  17. zookeeper基础知识以及常用命令
  18. c语言QQ管理系统四百条,C语言程序设计论文-工会成员信息管理系统.doc
  19. 在世界球场一球成名:HMS 生态为游戏开发者送出的助攻
  20. 深入浅出Java 23种设计模式,最全PDF版本终于开放下载了!!(文末有福利)

热门文章

  1. 经济学人 商论 倾听世界的声音 分享
  2. 数商云:钢铁企业以撮合模式切入B2B平台,汇聚势能实现价值最大化
  3. MAC 下屏蔽特定网址
  4. postgres 源码解析33 进程间通信--1
  5. 昨夜今天Tech圈:郭明錤预计苹果明年推两款5G iPhone 平井一夫正式退休
  6. 服务器维护玩穿越火线,为什么我玩穿越火线进不去 三招助你轻松进入游戏
  7. 海量数据处理:在100亿个数中找出top 10000
  8. Spring Data JPA问题汇总
  9. UE4导入人物模型后,材质没有对应的材质插槽,导致材质贴图混乱,的解决办法
  10. Android应用开发--MP3音乐播放器滚动歌词实现,flutter跳转动画