找回密码
 会员注册
查看: 19|回复: 0

前端富文本基础及实现

[复制链接]

2万

主题

0

回帖

6万

积分

超级版主

积分
64759
发表于 2024-10-10 11:24:30 | 显示全部楼层 |阅读模式
这是第153篇不掺水的,想要了解更多,请戳下方卡片关注我们吧~前端富文本基础及实现https://www.zoo.team/article/rich-text前言在日常生活中我们会经常接触到各种各样的文档格式和形式,其中富文本在文档格式中扮演了重要角色。对于前端而言,富文本产品也层出不穷,其应用也越来越广。这篇文章将会为大家介绍前端富文本的一些基础知识以及简单的实现思路。什么是富文本纯文本就是用纯文字编辑器编写,输入什么就是什么的文档,只包含字符。富文本对应的是富文本格式(Rich Text Format),即 RTF 格式,又称多文本格式,是由微软公司开发的跨平台文档格式。除字符外还有丰富的样式。doc,docx,rtf,pdf 等都是富文本格式的文件类型。如图所示:前端中的富文本前端富文本通过 html 的各个元素配合各种样式(一般是内联样式)实现。例如:富文本编辑器中的富文本,是由红色框中带有语义化标签和内联样式的 html 渲染实现的。通过富文本编辑器,即可实现富文本的编写、展示。目前常见的前端富文本编辑器有 tinymce,UEeditor,draft 等。文章下文将会讲述实现前端富文本编辑器的一些基础知识和步骤。富文本输入模式实现实现前端富文本编辑器首先要实现文本输入,一般常用两种方式实现。iframe第一种方式是使用 iframe 标签。在空白的 HTML 文档中嵌入一个 iframe,并将 designMode 属性设置为 on,文档就会变成可编辑的,实际编辑的则是 iframe 内的 body 元素。文档变成可编辑后,就可以像使用文字处理程序一样编辑文本。效果如图:元素设置 contenteditable第二种方式是使用 contenteditable 属性指定 HTML 文档中的元素。该方式是 IE 最早实现的。使用方式是在一个元素上添加 contenteditable 属性并设置为 true,然后该元素会立即被用户编辑。此种方式通常会和 autocapitalize(首字母自动大写属性)、spellcheck(检查元素的拼写错误,实验功能)等属性共同使用以提升体验。效果如图:两者特点两种方式都可以实现编辑模式,并且这种编辑模式与 textarea 不同,其内部会用块级元素(默认为 div 元素)做换行处理,最终体现在 dom 结构中。两者不同的是:iframe 方式可做到样式隔离,内部样式与外部样式不存在污染与冲突( tinymce 实现方式);元素设置 contentEditable 的方式( wangEditor 等实现方式)则和其他元素一样受到页面 css 作用。个人认为两者没有优劣之分,开发者根据自身需求选择即可。富文件选区富文本编辑中我们在进行编辑时首先会先选择一块文本区域(即选区),比如选择一段文字并进行字体加粗等操作,那么选区本身包含了哪些信息呢,下面为大家简单介绍一下。Selection 对象表示用户选择的文本范围或插入符号的当前位置。它代表页面中的文本选区,可能横跨多个元素。文本选区由用户拖拽鼠标经过文字而产生。调用 window.getSelection()(https://developer.mozilla.org/zh-CN/docs/Web/API/Window/getSelection) 可得到此对象,其内部常用属性如下:anchorNode返回选中区域对应的节点anchorOffset返回选中区域的起始下标,需要注意起始下标会根据左右方向选择的次序不同来展示不同的下标。如果 anchorNode 是字符串则对应文字下标,anchorNode 是元素,则对应选中区域对应它之前的同级节点的数目。focusNode返回选中区域终点所在的节点。focusOffset与 anchorOffset 类似,如果是 focusNode 是字符串,则对应最后一个选中的字符所在的位置,focusOffset 是元素,则对应选中区域对应同级节点的总数。rangeCount返回选中的区域所对应的连续的范围内的数量。type返回选中区域所对应的类别是连续 (Range),还是同一个位置的 (Caret)。我们常通过 anchorNode 与 anchorOffset 属性判断选区起始位置,通过 focusNode 与 focusOffset 属性判断选区终止位置。选区示例如图:anchorNode 为选区起始位置所在节点("政采云"文本节点),focusNode 为选区结束位置所在节点("ZOO" 文本节点),anchorOffset 与 focusOffset 分别为起始位置的 index,通过此信息可得到选区范围,此时 Selection 对象 type 为 Range。光标示例(起始位置是同一个位置的选区)如图:anchorNode 与 focusNode 为同一节点 ("ZOO" 文本节点),anchorOffset 与 focusOffset 指向节点同一处,通过此信息可得到光标位置,此时 Selection 对象 type 为 Caret。用途删除、替换选区内容&插入操作Selection 对象有 deleteFromDocument(https://developer.mozilla.org/zh-CN/docs/Web/API/Selection/deleteFromDocument) 方法,可以在编辑区域删除选区内容。如想删除后插入,可获取新的 Selection 对象,利用此时位置所在 dom 元素的方法插入对应的文字、元素。效果如图:插入逻辑代码如下:constinsert=()=>{//删除所选内容window.getSelection().deleteFromDocument()constselection=window.getSelection()//删除后选取的起始位置就是插入位置,由anchorNode及anchorOffset确定const{anchorNode,anchorOffset}=selection//anchorNode分为两种情况,一种是文本节点,另一种是其他类型节点,处理逻辑不同if(anchorNode.nodeType===3){conststring=anchorNode.nodeValue//anchorNode为文本节点时,需要将内部字符串与索要插入的内容拼接anchorNode.nodeValue=(string.substring(0,anchorOffset)+''+string.substring(anchorOffset,Infinity))}else{constnewNode=document.createElement('span')newNode.innerText=''//anchorNode为其他类型节点时,需要根据anchorOffset在anchorNode中插入片元素anchorNode.insertBefore(newNode,anchorNode.childNodes[anchorOffset])}}//也可根据Selection提供的原生方法实现constinsert2=()=>{lastRange=window.getSelection().getRangeAt(0);constnewNode=document.createElement('span');newNode.textContent=''lastRange.deleteContents()lastRange.insertNode(newNode)}关于选区的更多用途,可参考选区属性和方法进行灵活实现:https://developer.mozilla.org/zh-CN/docs/Web/API/Selection#methods富文本工具栏实现根据前文介绍的方法实现输入功能后,我们即实现了纯文本编辑的功能,那么如何进一步实现富文本编辑呢?document 提供了 execCommand() 方法,该方法会影响使用 designMode 或 contentEditable 属性实现可编辑区域的元素。方法说明如下所示:document.execCommand(aCommandName, aShowDefaultUI, aValueArgument)aCommandName一个 DOMString(https://developer.mozilla.org/zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/String_6fa58bba0570d663099f0ae7ae8883ab) ,命令的名称。可用命令列表请参阅 命令 (https://developer.mozilla.org/zh-CN/docs/Web/API/Document/execCommand#%E5%91%BD%E4%BB%A4) 。aShowDefaultUI一个 Boolean(https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Boolean), 是否展示用户界面,一般为 false。Mozilla 没有实现。aValueArgument一些命令(例如 insertImage)需要额外的参数(insertImage 需要提供插入 image 的 url),默认为 null。该方法执行后,会返回 boolean 值,如果是 false,表示操作不被支持或未被启用。不同浏览器支持的命令也不一样。下方标列出了最常用的命令。命令作用可选值backColor设置文档背景颜色。在 styleWithCss 模式下,则只影响容器元素的背景颜色。颜色值字符串(IE 使用这个命令设置文本背景色)bold切换选中文本的粗体样式nullcreateLink将选中内容转换为指向给定 URL的链接URL 链接值,至少包含一个字符fontSize将选中文本改为指定字体大小提供 HTML 字体尺寸 (1-7)foreColor将选中文本改为指定颜色颜色值字符串formatBlock将选中文本包含在指定的 HTML标签中提供 HTML 标签,如insertImage在光标位置插入图片图片的 URL 链接insertParagraph在光标位置插入元素nullitalic切换选中文本的斜体样式nullstyleWithCSS用这个取代 useCSS 命令。切换使用 HTML tags 还是 CSS 来生成标记。Boolean 值,false 使用CSS,true 使用 HTML关于 document.exexCommand 的更多命令,可参考 (https://developer.mozilla.org/zh-CN/docs/Web/API/Document/execCommand)常用功能(字体样式、插入图片)演示下图挑选了几个常用命令(加粗、斜体、改变字体颜色、插入图片)作为演示:代码示例如下://加粗constbold=(val)=>{document.execCommand('StyleWithCSS',true,true)document.execCommand('Bold',false,val)}//斜体constitalic=(val)=>{document.execCommand('StyleWithCSS',true,true)document.execCommand('italic',false,val)}//改变字体颜色constchangeColor=(val='#ff0000')=>{document.execCommand('StyleWithCSS',true,true)document.execCommand('foreColor',false,val)}//插入图片constinsertImage=(val='https://avatar-static.segmentfault.com/339/131/3391311562-5d5653daaad5f_huge256')=>{document.execCommand('StyleWithCSS',true,true)document.execCommand('insertImage',false,val)}富文本数据收集存储与回填富文本容器的 innerHTML 即是富文本数据。编辑区域可通过获取编辑元素的 innerHTML 拿到对应富文本数据,存入数据库。网络请求的富文本数据设置为富文本容器的 innerHTML,即可展示富文本内容。下列图片可简单表明:结尾(附 Demo)根据本文介绍内容我们依次了解了前端富文本的概念、输入模式实现、选区的信息及应用、富文本工具栏的实现和富文本数据收集回填。将这些内容汇总即可实现一个简单的前端富文本编辑器。下方附上本文内容汇总的代码 demo ,内含基于 iframe 和 div 元素分别实现的富文本编辑器,功能简单,供读者参考。读者可根据文章内容进行拓展实现自己的前端富文本编辑器。-------------------------------------------------------------- 粗体斜体改变颜色插入图片插入字符(表情) 元素设置contenteditable -------------------------------------------------------------- //元素设置contenteditable方式政采云前端团队------------------------------------------------------------------ iframe粗体 iframe设置designMode //iframe设置designMode方式 ------------------------------------------------------------------政采云前端团队ZOOTEAM效果如图:看完两件事如果你觉得这篇内容对你挺有启发,我想邀请你帮我两件小事1.点个「在看」,让更多人也能看到这篇内容(点了「在看」,bug -1 )2.关注公众号「政采云前端团队」,持续为你推送精选好文招贤纳士政采云前端团队(ZooTeam),一个年轻富有激情和创造力的前端团队,隶属于政采云产品研发部,Base 在风景如画的杭州。团队现有 90 余个前端小伙伴,平均年龄 27 岁,近 3 成是全栈工程师,妥妥的青年风暴团。成员构成既有来自于阿里、网易的“老”兵,也有浙大、中科大、杭电等校的应届新人。团队在日常的业务对接之外,还在物料体系、工程平台、搭建平台、性能体验、云端应用、数据分析及可视化等方向进行技术探索和实战,推动并落地了一系列的内部技术产品,持续探索前端技术体系的新边界。如果你想改变一直被事折腾,希望开始能折腾事;如果你想改变一直被告诫需要多些想法,却无从破局;如果你想改变你有能力去做成那个结果,却不需要你;如果你想改变你想做成的事需要一个团队去支撑,但没你带人的位置;如果你想改变既定的节奏,将会是“5 年工作时间 3 年工作经验”;如果你想改变本来悟性不错,但总是有那一层窗户纸的模糊… 如果你相信相信的力量,相信平凡人能成就非凡事,相信能遇到更好的自己。如果你希望参与到随着业务腾飞的过程,亲手推动一个有着深入的业务理解、完善的技术体系、技术创造价值、影响力外溢的前端团队的成长历程,我觉得我们该聊聊。任何时间,等着你写点什么,发给 ZooTeam@cai-inc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2024-12-28 21:45 , Processed in 0.459046 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表