高级JavaScript。如何用JavaScript手撸一个富文本编辑器?

36 篇文章 0 订阅
12 篇文章 0 订阅

要素过多建议收藏


- 富文本编辑

基本的技术就是在空白 HTML 文件中嵌入一个
iframe 。通过 designMode 属性,可以将这个空白文档变成可以编辑的,实际编辑的则是 <body> 元素
HTML designMode 属性有两个可能的值: "off" (默认值)和 "on" 。设置为 "on" 时,整个文档
都会变成可以编辑的(显示插入光标),从而可以像使用文字处理程序一样编辑文本,通过键盘将文本
标记为粗体、斜体,等等。
作为 iframe 源的是一个非常简单的空白 HTML 页面。下面是一个例子:
<!DOCTYPE html>
<html>
	<head>
		<title>Blank Page for Rich Text Editing</title>
	</head>
	<body>
	</body>
</html>
这个页面会像其他任何页面一样加载到 iframe 里。为了可以编辑,必须将文档的 designMode
性设置为 "on" 。不过,只有在文档完全加载之后才可以设置。在这个包含页面内,需要使用 onload
事件处理程序在适当时机设置 designMode ,如下面的例子所示:
<iframe name="richedit" style="height: 100px; width: 100px"></iframe> 
<script> 
 window.addEventListener("load", () => { 
 frames["richedit"].document.designMode = "on"; 
 }); 
</script>
以上代码加载之后,可以在页面上看到一个类似文本框的区域。这个框的样式具有网页默认样式,
不过可以通过 CSS 调整。

- 使用 contenteditable

还有一种处理富文本的方式,也是 IE 最早实现的,即指定 contenteditable 属性。可以给页面
中的任何元素指定 contenteditable 属性,然后该元素会立即被用户编辑。这种方式更受欢迎,因为
不需要额外的 iframe 、空页面和 JavaScript ,只给元素添加一个 contenteditable 属性即可,比如:
<div class="editable" id="richedit" contenteditable ></div>
元素中包含的任何文本都会自动被编辑,元素本身类似于 <textarea> 元素。通过设置
contentEditable 属性,也可以随时切换元素的可编辑状态:
let div = document.getElementById("richedit");
richedit.contentEditable = "true";
contentEditable 属性有 3 个可能的值: "true" 表示开启, "false" 表示关闭, "inherit" 表示
继承父元素的设置(因为在 contenteditable 元素内部会创建和删除元素)。 IE Firefox Chrome
Safari Opera 及所有主流移动浏览器都支持 contentEditable 属性。

- 与富文本交互

与富文本编辑器交互的主要方法是使用 document.execCommand() 。这个方法在文档上执行既定
的命令,可以实现大多数格式化任务。 document.execCommand() 可以接收 3 个参数:要执行的命令、
表示浏览器是否为命令提供用户界面的布尔值和执行命令必需的值(如果不需要则为 null )。为跨浏览
器兼容,第二个参数应该始终为 false ,因为 Firefox 会在其为 true 时抛出错误。
不同浏览器支持的命令也不一样。下表列出了最常用的命令。

 

剪贴板相关的命令与浏览器关系密切。虽然这些命令并不都可以通过 document.execCommand()
使用,但相应的键盘快捷键都是可以用的。
这些命令可以用于修改内嵌窗格( iframe )中富文本区域的外观,如下面的例子所示:
// 在内嵌窗格中切换粗体文本样式
frames["richedit"].document.execCommand("bold", false, null);
// 在内嵌窗格中切换斜体文本样式
frames["richedit"].document.execCommand("italic", false, null);
// 在内嵌窗格中创建指向 www.wrox.com 的链接
frames["richedit"].document.execCommand("createlink", false,
"http://www.wrox.com");
// 在内嵌窗格中为内容添加 <h1> 标签
frames["richedit"].document.execCommand("formatblock", false, "<h1>");
同样的方法也可以用于页面中添加了 contenteditable 属性的元素,只不过要使用当前窗口而不
是内嵌窗格中的 document 对象:
// 切换粗体文本样式
document.execCommand("bold", false, null);
// 切换斜体文本样式
document.execCommand("italic", false, null);
// 创建指向 www.wrox.com 的链接
document.execCommand("createlink", false, "http://www.wrox.com");
// 为内容添加 <h1> 标签
document.execCommand("formatblock", false, "<h1>");

 

注意,即使命令是所有浏览器都支持的,命令生成的 HTML 通常差别也很大。例如,为选中文本
应用 bold 命令在 IE Opera 中会使用 <strong> 标签,在 Safari Chrome 中会使用 <b>标签,而在Firefox 中会使用 <span> 标签。在富文本编辑中,不能依赖浏览器生成的 HTML,因为命令实现和格式 转换都是通过 innerHTML 完成的。
还有与命令相关的其他一些方法。第一个方法是 queryCommandEnabled() ,此方法用于确定对当
前选中文本或光标所在位置是否可以执行相关命令。它只接收一个参数,即要检查的命令名。如果可编 辑区可以执行该命令就返回 true ,否则返回 false 。来看下面的例子:
let result = frames["richedit"].document.queryCommandEnabled("bold");
以上代码在当前选区可以执行 "bold" 命令时返回 true 。不过要注意, queryCommandEnabled()
返回 true 并不代表允许执行相关命令,只代表当前选区适合执行相关命令。在 Firefox 中,
queryCommandEnabled("cut") 即使默认不允许剪切也会返回 true
另一个方法 queryCommandState() 用于确定相关命令是否应用到了当前文本选区。例如,要确定
当前选区的文本是否为粗体,可以这样:
let isBold = frames["richedit"].document.queryCommandState("bold");
如果之前给文本选区应用过 "bold" 命令,则以上代码返回 true 。全功能富文本编辑器可以利用这
个方法更新粗体、斜体等按钮。
最后一个方法是 queryCommandValue() ,此方法可以返回执行命令时使用的值(即前面示例的
execCommand() 中的第三个参数)。如果对一段选中文本应用了值为 7 "fontsize"命令,则如下代 码会返回 7
let fontSize = frames["richedit"].document.queryCommandValue("fontsize");
这个方法可用于确定如何将命令应用于文本选区,从而进一步决定是否需要执行下一个命令。

- 富文件选择 

在内嵌窗格中使用 getSelection() 方法,可以获得富文本编辑器的选区。这个方法暴露在
document window 对象上,返回表示当前选中文本的 Selection 对象。每个 Selection 对象都拥
有以下属性。
anchorNode :选区开始的节点。
anchorOffset :在 anchorNode 中,从开头到选区开始跳过的字符数。
focusNode :选区结束的节点。
focusOffset focusNode 中包含在选区内的字符数。
isCollapsed :布尔值,表示选区起点和终点是否在同一个地方。
rangeCount :选区中包含的 DOM 范围数量。
Selection 的属性并没有包含很多有用的信息。好在它的以下方法提供了更多信息,并允许操作
选区。
addRange( range ) :把给定的 DOM 范围添加到选区。
collapse( node, offset ) :将选区折叠到给定节点中给定的文本偏移处。
collapseToEnd() :将选区折叠到终点。
collapseToStart() :将选区折叠到起点。
containsNode( node ) :确定给定节点是否包含在选区中。
deleteFromDocument() :从文档中删除选区文本。与执行 execCommand("delete", false,
null) 命令结果相同。
extend( node, offset ) :通过将 focusNode focusOffset 移动到指定值来扩展选区。
getRangeAt( index ) :返回选区中指定索引处的 DOM 范围。
removeAllRanges() :从选区中移除所有 DOM 范围。这实际上会移除选区,因为选区中至少
要包含一个范围。
removeRange( range ) :从选区中移除指定的 DOM 范围。
selectAllChildren( node ) :清除选区并选择给定节点的所有子节点。
toString() :返回选区中的文本内容。
Selection 对象的这个方法极其强大,充分利用了 DOM 范围来管理选区。操纵 DOM 范围可以实
现比 execCommand() 更细粒度的控制,因为可以直接对选中文本的 DOM 内容进行操作。来看下面的 例子:
let selection = frames["richedit"].getSelection(); 
// 取得选中的文本
let selectedText = selection.toString(); 
// 取得表示选区的范围
let range = selection.getRangeAt(0); 
// 高亮选中的文本
let span = frames["richedit"].document.createElement("span"); 
span.style.backgroundColor = "yellow"; 
range.surroundContents(span);
以上代码会在富文本编辑器中给选中文本添加黄色高亮背景。实现方式是在默认选区使用 DOM
围,用 surroundContents() 方法给选中文本添加背景为黄色的 <span> 标签。
getSelection() 方法在 HTML5 中进行了标准化, IE9 以及 Firefox Safari Chrome Opera 的所
有现代版本中都实现了这个方法。
IE8 及更早版本不支持 DOM 范围,不过它们允许通过专有的 selection 对象操作选中的文本。如
本章前面所讨论的,这个 selection 对象是 document 的属性。要取得富文本编辑器中选中的文本, 必须先创建一个文本范围,然后再访问其 text 属性:
let range = frames["richedit"].document.selection.createRange(); 
let selectedText = range.text;
使用 IE 文本范围执行 HTML 操作不像使用 DOM 范围那么可靠,不过也是可以做到的。要实现与
使用 DOM 范围一样的高亮效果,可以组合使用 htmlText 属性和 pasteHTML() 方法:
let range = frames["richedit"].document.selection.createRange(); 
range.pasteHTML( 
 '<span style="background-color:yellow">${range.htmlText}</span>');
以上代码使用 htmlText 取得了当前选区的 HTML ,然后用一个 <span> 标签将其包围起来并通过
pasteHTML() 再把它插入选区中。
  • 25
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 富文本编辑器是一种能够让用户在编辑文本时进行格式化的工具。要编写一个完整的富文本编辑器,需要考虑以下几个方面: 1. 用户界面:编辑器需要有一个易于使用和直观的用户界面,包括菜单、工具栏和编辑区。 2. 文本编辑:编辑器需要能够支持常见的文本编辑功能,如插入文本、删除文本、复制和粘贴文本等。同时,编辑器也需要能够支持撤销和重做功能,以便用户在编辑过程中能够轻松地撤销和恢复之前的操作。 3. 文本格式:编辑器需要支持各种文本格式,如加粗、倾斜、下划线、字体、字号等。同时,编辑器还应该支持多种颜色、对齐方式、列表、表格等格式。 4. 图片和多媒体:编辑器需要支持插入图片和其他多媒体元素,例如音频和视频。 5. 导出文本:编辑器需要能够将编辑的文本导出为各种格式,如HTML、Markdown、PDF等,以方便用户在不同的场合下使用。 要实现一个完整的富文本编辑器需要一定的编程技术和知识,可以使用各种编程语言和框架,如JavaScript、React、Angular、Vue.js等。同时,也可以使用现成的编辑器组件库,如Quill、TinyMCE、CKEditor等,这些组件库已经实现了上述功能,可以方便地嵌入到自己的应用程序中。 ### 回答2: 要编写一个完整的富文本编辑器,需要涉及以下几个方面: 1. 用户界面设计:首先,需要设计一个用户界面来显示文本编辑器的各种功能和选项。可以使用HTML和CSS来创建一个界面,包括菜单栏、工具栏、编辑区域等。 2. 文本输入与输出:用户可以通过编辑区域输入和编辑文本内容。编辑器应该支持基本的文本输入和选择,包括插入、删除、复制、粘贴等操作。同时,编辑器还需要支持文本的撤销和恢复功能。 3. 格式化功能:富文本编辑器应该支持文本的格式化功能,比如文字的加粗、斜体、下划线、字号、字体等。这些格式化选项可以通过工具栏或者菜单栏进行选择和设置。 4. 图片和多媒体支持:编辑器还应该支持插入图片和多媒体内容。通过选择图片和视频文件,编辑器可以将其插入到文本中,并且支持对其进行调整和格式化。 5. 链接与超链接:编辑器应该支持超链接的插入和编辑。用户可以在文本中插入链接,并设置链接的目标地址和显示文本。 6. 自动保存与恢复:编辑器可以提供自动保存和恢复功能,以防止用户在编辑文本时意外丢失内容。通过定时保存用户输入的文本内容,可以在发生意外情况时进行恢复。 7. 导出与打印:编辑器应该支持将编辑好的文本内容导出为HTML、PDF或其他格式文件。同时,还应该支持打印功能,使用户可以直接打印编辑好的文档。 8. 兼容性与性能优化:要确保编辑器在不同的浏览器和操作系统上都可以正常运行,并且能够处理大文本文件的编辑,尽量减少性能瓶颈。 综上所述,一个完整的富文本编辑器应该具备上述功能,满足用户对编辑文本的基本需求,并提供友好的用户界面和良好的使用体验。 ### 回答3: 一个完整的富文本编辑器一个功能强大的工具,允许用户在编辑文本时进行各种格式设置和实时预览。下面是一个简单的描述: 首先,富文本编辑器需要提供一个编辑界面,其中包含一个文本输入框,用于用户输入文本内容。用户可以使用该文本输入框输入任何文本,并对其进行格式设置。 其次,富文本编辑器应该提供基本的文本格式设置选项,如加粗、斜体、下划线、字体和字号等。用户可以使用这些选项来改变文本的外观。 此外,富文本编辑器还应该支持更高级的格式设置选项,如文本对齐、行距和首行缩进等。用户可以使用这些选项来进一步调整文本的布局和样式。 除了文本格式设置外,富文本编辑器还应该提供插入图片和链接的功能。用户可以上传图片或插入网络图片,并可以通过链接插入超链接。 另外,富文本编辑器还可以提供查找和替换文本的功能,使用户能够方便地查找并替换特定的文字。 最后,富文本编辑器还应该支持实时预览功能,允许用户在编辑时即时查看文本的最终显示效果。 综上所述,一个完整的富文本编辑器应该包括文本输入框、基本的文本格式设置选项、高级的格式设置选项、插入图片和链接的功能、查找和替换文本的功能以及实时预览功能。这样的富文本编辑器可以满足用户在编辑文本时的各种需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝斑.json (前端)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值