专栏首页云前端富文本编辑器开发简介

富文本编辑器开发简介

前言

富文本编辑器,Rich Text Editor, 简称 RTE, 是一种可内嵌于浏览器,所见即所得的文本编辑器。

方式

iframe

页面中嵌入一个包含空HTML页面的iframe。设置designMode属性,使空白页面HTML的body可以被编辑。

designMode:off/on

* 页面加载完才可以设置designMode属性,所以需要使用onload事件。

<iframe name="demoDesignMode" src="demoDesignMode.html" style="height: 100px;width: 100px;"></iframe>
<script>
   window.onload= function(){
       frames['demoDesignMode'].document.designMode = 'on';
   }
</script>

contenteditable

contenteditable='true'设置元素和它包含的元素可以编辑。

* 区分contenteditable和contentEditable。contenteditable是元素的特性,而contentEditable是对象的属性。

<div id="box" style="height: 100px;width: 100px; border:1px solid black"></div>
<button id="btn1">打开富文本编辑</button>
<button id="btn2">关闭富文本编辑</button>    
<script>
   btn1.onclick = function(){box.contentEditable = true;}
   btn2.onclick = function(){box.contentEditable = false;}
</script>

命令

document.execCommand()对文档执行预定义的命令。

document.execCommand(String aCommandName, Boolean aShowDefaultUI, String aValueArgument):

  • aCommandName

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

  • aShowDefaultUI

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

  • aValueArgument

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

* 因为浏览器兼容性问题,第二个参数要为false,firefox在该参数为true时抛出错误。

格式段落

居中   document.execCommand('justifyCenter');

左对齐    document.execCommand('justifyLeft');

右对齐 document.execCommand('justifyRight');

添加缩进   document.execCommand('indent');

去掉缩进   document.execCommand('outdent');

文本格式

字体类型  document.execCommand('fontname',false,sFontName)

字体大小  document.execCommand('fontsize',false,sFontSize)

字体颜色   document.execCommand('forecolor',false,sFontColor)

背景色 document.execCommand('backColor',false,sBackColor)

加粗   document.execCommand('bold');

斜体   document.execCommand('italic');

下划线 document.execCommand('underline');

编辑

复制   document.execCommand('copy');

剪切   document.execCommand('cut');

粘贴   document.execCommand('paste');(经测试无效)

全选   document.execCommand('selectAll');

删除   document.execCommand('delete');

后删除 document.execCommand('forwarddelete');

清空格式   document.execCommand('removeFormat');

前进一步   document.execCommand('redo');

后退一步   document.execCommand('undo');

打印    document.execCommand('print');(对firefox无效)

插入

插入标签    document.execCommand('formatblock',false,elementName);

插入<hr> document.execCommand('inserthorizontalrule');

插入<ol>   document.execCommand('insertorderedlist');

插入<ul>   document.execCommand('insertunorderedlist');

插入<p> document.execCommand('insertparagraph');

插入图像    document.execCommand('insertimage',false,URL);

增加链接    document.execCommand('createlink',false,URL);

删除链接    document.execCommand('unlink');

选区

getSelection()方法

属性

  • anchorNode:选区起点所在的节点
  • anchorOffset:在到达选区起点位置之前跳过的anchorNode中的字符数量
  • focusNode:选区终点所在的节点
  • focusOffset:focusNode中包含在选区之内的字符数量
  • isCollapsed:布尔值,表示选区的起点和终点是否重合
  • rangeCount:选区中包含的DOM范围的数量

方法

  • addRange(range):将指定的DOM范围添加到选区中
  • collapse(node,offset):将选区折叠到指定节点中的相应的文本偏移位置
  • collapseToEnd():将选区折叠到终点位置
  • collapseToStart():将选区折叠到起点位置
  • containsNode(node):确定指定的节点是否包含在选区中
  • deleteFromDocument():从文档中删除选区中的文本,与document.execCommand("delete",false,null)命令的结果相同
  • extend(node,offset):通过将focusNode和focusOffset移动到指定的值来扩展选区
  • getRangeAt(index):返回索引对应的选区中的DOM范围
  • removeAllRanges():从选区中移除所有DOM范围。实际上,这样会移除选区,因为选区中至少要有一个范围
  • reomveRange(range):从选区中移除指定的DOM范围
  • selectAllChildren(node):清除选区并选择指定节点的所有子节点
  • toString():返回选区所包含的文本内容

* IE8-浏览器不支持,我试了IE8以上也不支持

selection对象

术语

  • anchor:选中区域的“起点”。
  • focus:选中区域的“结束点”。
  • range:是一种fragment(HTML片断),它包含了节点或文本节点的一部分。

属性

  • anchorNode:返回包含“起点”的节点。
  • anchorOffset:“起点”在anchorNode中的偏移量。
  • focusNode:返回包含“结束点”的节点。
  • focusOffset:“结束点”在focusNode中的偏移量。
  • isCollapsed:“起点”和“结束点”是否重合。
  • rangeCount:返回selection中包含的range对象的数目,一般存在一个range,Ctrl健配合使用可以有多个。

方法

  • getRangeAt(index):从当前selection对象中获得一个range对象。
  • collapse(parentNode, offset):将开始点和结束点合并到指定节点(parentNode)的相应(offset)位置。
  • extend(parentNode, offset): 将“结束点”移动到指定节点(parentNode)的指定位置(offset)。
  • modify(alter, direction, granularity): 改变焦点的位置,或扩展|缩小selection的大小。
  • collapseToStart():将“结束点”移动到,selction的“起点”,多个range时也是如此。
  • collapseToEnd():将“起点”移动到,selction的“结束点”,多个range时也是如此。
  • selectAllChildren(parentNode):将parentNode的所有后代节点(parentNode除外)变为selection,页面中原来的selection将被抛弃。
  • apRange(range):将range添加到selection当中,所以一个selection中可以有多个range。
  • removeRange(range):从当前selection移除range对象,返回值undefined。
  • removeAllRanges():移除selection中所有的range对象,执行后anchorNode、focusNode被设置为null,不存在任何被选中的内容。
  • toString():返回selection的纯文本,不包含标签。
  • containsNode(aNode, aPartlyContained): 判断一个节点是否是selction的一部分。

表单提交

富文本编辑不是使用表单控件实现的,而需要手工来提取并提交HTML。为此,通常可以添加一个隐藏的表单字段,就是在提交表单之前提取出HTML,并将其插入到隐藏的字段中。

iframe

    form.onsubmit = function(e){
   e = e || event;
   var target = e.target || e.srcElement;
   target.elements["comments"].value = frames["richedit"].document.body.innerHTML;
   }

contenteditable

    form.onsubmit = function(e){
   e = e || event;
   var target = e.target || e.srcElement;
   target.elements["comments"].value = document.getElementById('wysiwyg').innerHTML;
   }

实战

结构

    <div id="editor-box">
       <div id="editor-icon">
           <div class="icon-box">
               <span class="glyphicon glyphicon-bold" data-role="bold">加粗</span>
               <span class="glyphicon glyphicon-italic" data-role="italic">斜体</span>
               <span class="glyphicon glyphicon-align-center" data-role="justifyCenter">居中</span>
               <span class="glyphicon glyphicon-align-left" data-role="justifyLeft">左对齐</span>
               <span class="glyphicon glyphicon-align-right" data-role="justifyRight">右对齐</span>
               <span class="glyphicon" data-role="indent">添加缩进</span>
               <span class="glyphicon" data-role="outdent">去掉缩进</span>
               <span class="glyphicon" data-role="h1">h1</span>
               <span class="glyphicon" data-role="h2">h2</span>
               <span class="glyphicon" data-role="p">p</span>
           </div>
       </div>
       <div id="editor" contenteditable="true">       </div>
   </div>

js

    $(document).ready(function(e) {
       $('.icon-box span').click(function(e) {           $('#editor').focus();
           getC($('#editor'))
           switch($(this).data('role')) {
               case 'h1':
               case 'h2':
               case 'p':
                   document.execCommand('FormatBlock', false, '<' + $(this).data('role') + '>');
                   console.log($(this).data('role'));
                   break;
               default:
                   document.execCommand($(this).data('role'), false, null);
                   break;
           }
       })
   });   function getC(that){
       if(document.all){
           that.range=document.selection.createRange();
           that.range.select();
           that.range.moveStart("character",-1);
       }else{
           that.range=window.getSelection().getRangeAt(0);
           that.range.setStart(that.range.startContainer, that.range.startContainer.length);
       }
   }

总结

实现一个富文本编辑器没有想的那么容易哦,这个只是简单的实践,实际是一个大工程哦。请看这个文章:

https://www.zhihu.com/question/38699645?sort=created

推荐几个编辑器:

widgEditor

wangeditor

ueditor

本文分享自微信公众号 - 云前端(fewelife),作者:小樊qq

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-10-24

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 简单的canvas绘图

    注意:默认情况下 <canvas> 元素没有边框和内容,width 和 height 属性定义的画布的大小.

    江米小枣
  • [译] 深入 React 高阶组件

    原文: https://medium.com/@franleplant/react-higher-order-components-in-depth-cf903...

    江米小枣
  • [译] 监听第三方 Vue 组件的生命周期钩子

    原文:https://vuedose.tips/listen-to-lifecycle-hooks-on-third-party-vue-js-componen...

    江米小枣
  • 必看的Linux服务器高并发调优实战

    来源:https://www.cnblogs.com/txlsz/p/13683892.html

    DevOps持续交付
  • 人人都会写的富文本编辑器

    这个本来是给 vm-manager 写的一个富文本编辑器,后来觉得独立出来维护比较方便,就单独分离出来放到NPM。之所以说人人都会写, 是因为这个组件实现起来确...

    前端博客 : alili.tech
  • SLAM技术课程总结

    如上都是客观原因,所有困难和学生并无太大关系,但结果还是非常让人满意的,完全达到应用型本科院校对于全体学生SLAM技术理论和实践的要求,只有极少数学生未能顺利完...

    zhangrelay
  • mysql已存在的表增加自增字段

    pollyduan
  • ASP.NET Core IP 请求频率限制

    在网站或API应用中,我们为了防止无聊人士或恶意攻击,通常希望屏蔽某一IP短时间的内高频率请求。在ASP.NET Core中,限制IP请求频率非常简单,我们来看...

    Edi Wang
  • cocos2d-x 学习笔录:将iOS项目编译成Andriod项目

    一、Android 环境搭建 1、安装Andriod-NDK(Native Development Kit)   新建一个文件夹(eg:NDK),解压Andro...

    猿人谷
  • Promise 必知必会(十道题)

    Promise 想必大家都十分熟悉,想想就那么几个 api,可是你真的了解 Promise 吗?本文根据 Promise 的一些知识点总结了十道题,看看你能做对...

    Nealyang

扫码关注云+社区

领取腾讯云代金券