所见即所得的编辑器非常受欢迎。 您可能在某个时候也使用过一个。 有很多库可以帮助您设置自己的编辑器。 尽管它们设置起来很快,但是使用这些库也有缺点。 首先,它们膨胀。 它们大多数具有您可能不会使用的精美功能。 此外,自定义这些编辑器的外观可能很麻烦。
在本教程中,我们将构建自己的轻量级所见即所得编辑器。 在本教程结束时,您将拥有一个具有基本格式化功能的编辑器,该编辑器可根据您的喜好进行样式设置。
让我们开始介绍execCommand
。 我们将使用此命令广泛地实现我们的编辑器。
Document.execCommand()
execCommand
是文档对象的方法。 它使我们能够操纵可编辑区域的内容。 与contentEditable
一起使用时,它可以帮助我们创建富文本编辑器。 有许多可用的命令,例如添加链接,将选项变为粗体或斜体以及更改字体大小或颜色。 此方法遵循以下语法:
document.execCommand(CommandName, ShowDefaultUI, ValueArgument);
CommandName
是一个字符串,它指定要执行的命令的名称。 ShowDefaultUI
是一个布尔值,指示是否应该显示支持界面。 此选项未完全实现,最好将其设置为false。 ValueArgument
是一个字符串,用于提供诸如图像URL或foreColor
。 当命令不需要值生效时,此参数设置为null
。
我们将需要使用此方法的不同版本来实现各种功能。 在接下来的几段中,我将一一介绍所有这些内容。
无值参数的命令
诸如粗体,对齐,撤消和重做之类的命令不需要ValueArgument
。 在这种情况下,我们使用以下语法:
document.execCommand(commandName, false, null);
CommandName
只是命令的名称,如justifyCenter
, justifyRight
, bold
等。
带有值参数的命令
像命令insertImage
, createLink
和foreColor
需要第三个参数正常工作。 对于这些命令,您需要以下语法:
document.execCommand(commandName, false, value);
对于insertImage
,该值将是要插入的图像的URL。 在foreColor
的情况下,它将是颜色值,例如#FF9966
或名称,例如blue
。
添加块样式标签的命令
添加HTML块样式标记要求您将formatBlock
用作commandName
,并将标记名用作valueArgument
。 语法类似于:
document.execCommand('formatBlock', false, tagName);
此方法将在包含当前选择的行周围添加HTML块样式标签。 它还会替换那里已经存在的任何标签。 tagName
可以是任何标题标签( h1
- h6
), p
或blockquote
。
我在这里讨论了最常见的命令。 您可以访问Mozilla以获取所有可用命令的列表。
创建工具栏
有了基础知识,现在该创建工具栏了。 我将在按钮上使用“ 真棒字体”图标。 您可能已经注意到,撇开一些差异,所有execCommand
都具有类似的结构。 通过对工具栏按钮使用以下标记,我们可以利用此优势:
<a href="#" data-command='commandName'><i class='fa fa-icon'></i></a>
这样,每当用户单击按钮时,我们就可以根据data-command
属性的值来确定要使用哪个版本的execCommand
。 以下是一些参考按钮:
<a href="#" data-command='h2'>H2</a>
<a href="#" data-command='undo'><i class='fa fa-undo'></i></a>
<a href="#" data-command='createlink'><i class='fa fa-link'></i></a>
<a href="#" data-command='justifyLeft'><i class='fa fa-align-left'></i></a>
<a href="#" data-command='superscript'><i class='fa fa-superscript'></i></a>
第一个按钮的data-command
属性值为h2
。 在JavaScript中检查了该值之后,我们将使用execCommand
方法的formatBlock
版本。 同样,对于最后一个按钮, superscript
建议我们需要使用execCommand
的no valueArgument
版本。
创建foreColor
和backColor
按钮是一个不同的故事。 他们提出了两个问题。 根据我们提供给用户的颜色数量的选择,编写那么多的代码可能会很累并且容易出错。 为了解决这个问题,我们可以使用以下JavaScript代码:
var colorPalette = ['000000', 'FF9966', '6699FF', '99FF66','CC0000', '00CC00', '0000CC', '333333', '0066FF', 'FFFFFF'];
var forePalette = $('.fore-palette');
for (var i = 0; i < colorPalette.length; i++) {
forePalette.append('<a href="#" data-command="forecolor" data-value="' + '#' + colorPalette[i] + '" style="background-color:' + '#' + colorPalette[i] + ';" class="palette-item"></a>');
}
请注意,我还在为每种颜色设置data-value
属性。 以后将在execCommand
方法中将其用作valueArgument
。
第二个问题是我们不能一直显示很多颜色,因为这会占用大量空间并导致糟糕的用户体验。 使用少量CSS,我们可以确保仅当用户将鼠标悬停在相应按钮上时才会显示调色板。 这些按钮的标记也需要更改为以下内容:
<div class="fore-wrapper"><i class='fa fa-font'></i>
<div class="fore-palette">
</div>
</div>
要仅在hover
上显示调色板,我们需要以下CSS:
.fore-palette,
.back-palette {
display: none;
}
.fore-wrapper:hover .fore-palette,
.back-wrapper:hover .back-palette {
display: block;
float: left;
position: absolute;
}
CodePen演示中还有很多其他CSS规则可以使工具栏更漂亮,但这是核心功能所需的全部。
向编辑器添加功能
现在,是时候使我们的编辑器起作用。 这样做所需的代码非常少。
$('.toolbar a').click(function(e) {
var command = $(this).data('command');
if (command == 'h1' || command == 'h2' || command == 'p') {
document.execCommand('formatBlock', false, command);
}
if (command == 'forecolor' || command == 'backcolor') {
document.execCommand($(this).data('command'), false, $(this).data('value'));
}
if (command == 'createlink' || command == 'insertimage') {
url = prompt('Enter the link here: ','http:\/\/');
document.execCommand($(this).data('command'), false, url);
}
else document.execCommand($(this).data('command'), false, null);
});
首先,将click事件附加到所有工具栏按钮上。 每当单击工具栏按钮时,我们会将相应按钮的data-command
属性的值存储在变量command
。 稍后将其用于调用相应版本的execCommand
方法。 它有助于编写简洁的代码,并避免重复。
当设置foreColor
和backColor
,我使用的data-value
属性作为第三个参数。 createLink
和insertImage
没有一个恒定url
值,因此我们使用的提示,从用户那里得到的值。 您可能还希望执行其他检查,以确保该url
有效。 如果command
变量不满足任何if
块,则运行execCommand
的第一个版本。
这就是我们所见即所得的编辑器的外观。
您还可以使用我在上一教程中讨论的localStorage
来实现自动保存功能。
跨浏览器差异
各种浏览器的实现差异很小。 例如,请记住,当使用formatBlock
,Internet Explorer仅支持标题标签h1 - h6
, address
和pre
。 在指定commandName
类的<h3>
时,还需要包括标签定界符。
并非所有浏览器都支持所有命令。 Internet Explorer不支持诸如insertHTML
和hiliteColor
命令。 同样,只有Firefox支持insertBrOnReturn
。 您可以在此GitHub页面上阅读有关浏览器不一致的更多信息。
最后的想法
创建自己的所见即所得编辑器可以是一个很好的学习经验。 在本教程中,我介绍了很多命令,并使用了一些CSS作为基本样式。 作为练习,我建议您尝试实现一个工具栏按钮以设置文本选择的font
。 该实现将与foreColor
按钮的实现类似。
希望您喜欢本教程并学到新知识。 如果您是从头开始创建自己的WYSIWYG编辑器的,请随时在评论部分中链接到它。