创建内联编辑器需要付出很多努力。 首先,使用input
或textarea
字段切换要编辑的元素。 为了获得无缝的用户体验,您可能还必须使用一些CSS才能将交换元素的样式与原始样式相匹配。 用户完成编辑后,将所有内容复制到原始内容后,您将不得不再次切换元素。
contentEditable
属性使此任务更加容易。 您所要做的就是将此属性设置为true
,标准HTML5元素将变为可编辑的。 在本教程中,我们将基于此功能创建内联富文本编辑器。
基础
此属性可以采用三个有效值。 这些是true
, false
和inherit
。 值为true
表示该元素是可编辑的。 空字符串也将评估为true。 false
表示该元素不可编辑。 值inherit
是默认值。 inherit
表示元素的直接父元素是可编辑的,那么它将是可编辑的。 这意味着,如果您将元素设为可编辑,则除非将其子元素的contentEditable
属性显式设置为false
,否则它的所有子元素(不仅是直接子元素)也将变为可编辑的。
您可以使用JavaScript动态更改这些值。 如果新值不是三个有效值中的任何一个,则它将引发SyntaxError异常。
创建编辑器
要创建内联编辑器,每当用户决定编辑某些contentEditable
时,您都需要能够更改contentEditable
属性的值。
在切换contentEditable
属性时,有必要知道该属性当前拥有什么值。 为此,可以使用isContentEditable
属性。 如果isContentEditable
对某个元素返回true
,则该元素当前可编辑,否则不可编辑。 我们将很快使用此属性来确定文档中各种元素的状态。
构建编辑器的第一步是创建一个按钮来切换编辑和一些可编辑的元素。
<button id="editBtn" type="button">Edit Document</button>
<div id="editor">
<h1 id="title">A Nice Heading.</h1>
<p>Last Edited By - <span id="author">Monty Shokeen</span></p>
<p id="content">Some content that needs correction.</p>
</div>
我们打算保持可编辑状态的每个元素都需要具有自己的唯一Id
。 当我们必须保存更改或以后检索它们以替换每个元素中的文本时,这将很有帮助。
以下JavaScript代码处理所有编辑和保存。
var editBtn = document.getElementById('editBtn');
var editables = document.querySelectorAll('#title, #author, #content')
editBtn.addEventListener('click', function(e) {
if (!editables[0].isContentEditable) {
editables[0].contentEditable = 'true';
editables[1].contentEditable = 'true';
editables[2].contentEditable = 'true';
editBtn.innerHTML = 'Save Changes';
editBtn.style.backgroundColor = '#6F9';
} else {
// Disable Editing
editables[0].contentEditable = 'false';
editables[1].contentEditable = 'false';
editables[2].contentEditable = 'false';
// Change Button Text and Color
editBtn.innerHTML = 'Enable Editing';
editBtn.style.backgroundColor = '#F96';
// Save the data in localStorage
for (var i = 0; i < editables.length; i++) {
localStorage.setItem(editables[i].getAttribute('id'), editables[i].innerHTML);
}
}
});
我们使用querySelectorAll()
将所有可编辑元素存储在变量中。 此方法返回一个NodeList
,其中包含我们文档中所有与指定选择器匹配的元素。 这样,使用一个变量跟踪可编辑元素会更容易。 例如,可以使用editables[0]
访问文档的标题,这是我们接下来要做的。
接下来,我们将事件侦听器添加到按钮的click事件中。 每次用户单击“编辑文档”按钮时,我们都会检查标题是否可编辑。 如果它不可编辑,则将每个可编辑元素的contentEditable
属性设置为true
。 此外,文本'Edit Document'
更改为'Save Changes'
。 用户进行了一些编辑后,他们可以单击'Save Changes'
按钮,所做的更改可以永久保存。
如果标题是可编辑的,则将每个可编辑元素的contentEditable
属性设置为false。 此时,我们还可以将文档的内容保存在服务器上,以供日后检索或将更改同步到其他地方存在的副本。 在本教程中,我将所有内容都保存在localStorage
。 将值保存在localStorage
,我使用每个元素的Id
来确保不覆盖任何内容。
检索保存的内容
如果您对上一个演示中的任何元素进行更改并重新加载页面,您将注意到所做的更改已消失。 这是因为没有适当的代码来检索保存的数据。 将内容保存在localStorage
,我们需要在用户再次访问网页时稍后对其进行检索。
if (typeof(Storage) !== "undefined") {
if (localStorage.getItem('title') !== null) {
editables[0].innerHTML = localStorage.getItem('title');
}
if (localStorage.getItem('author') !== null) {
editables[1].innerHTML = localStorage.getItem('author');
}
if (localStorage.getItem('content') !== null) {
editables[2].innerHTML = localStorage.getItem('content');
}
}
上面的代码检查标题,作者或内容在localStorage
已存在。 如果是这样,我们将各个元素的innerHTML
设置为检索到的值。
使编辑器更加用户友好
为了进一步改进内联编辑器,我们需要进行两项更改。 第一个是要在可编辑内容与不可编辑内容之间做出明确区分。 这可以通过使用CSS更改可编辑元素的外观来实现。 更改相关元素的字体和颜色应该可以解决问题。 每当contenteditable
属性设置为true
时, [contenteditable="true"]
选择器将对元素应用以下样式。
[contenteditable="true"] {
font-family: "Rajdhani";
color: #C00;
}
第二个改进是自动保存数据的能力。 您可以通过多种方式进行操作,例如每五秒钟自动保存一次。
setInterval(function() {
for (var i = 0; i < editables.length; i++) {
localStorage.setItem(editables[i].getAttribute('id'), editables[i].innerHTML);
}
}, 5000);
您还可以保存每个keydown
事件的更改。
document.addEventListener('keydown', function(e) {
for (var i = 0; i < editables.length; i++) {
localStorage.setItem(editables[i].getAttribute('id'), editables[i].innerHTML);
}
});
在本教程中,我坚持使用前一种方法。 您可以根据项目中似乎更合适的任何事件来触发自动保存。
使用设计模式编辑整个页面
当您必须编辑网页上的一些元素时, contentEditable
很有用。 当必须更改网页上所有或几乎所有元素的内容时,可以使用designMode
属性。 此属性适用于整个文档。 要将其on
和off
,可以使用document.designMode = 'on';
和document.designMode = 'off';
分别。
在您是设计师而其他人是内容创建者的情况下,这将被证明很有价值。 您为他们提供了设计和一些伪文本。 以后,他们可以将其替换为实际内容。 要查看designMode
中的designMode
,请在浏览器的开发人员工具中打开“控制台”选项卡。 键入document.designMode = 'on';
进入控制台,然后按Enter 。 此页面上的所有内容现在都可以编辑。
最后的想法
contentEditable
属性在诸如快速编辑文章或使用户单击即可编辑其注释的情况下非常方便。 此功能最早是由IE 5.5实现的。 后来,它由WHATWG标准化。 浏览器支持也很好。 除了Opera Mini之外,所有主流浏览器都支持此属性。
JavaScript已成为事实上的网络工作语言之一。 这并非没有学习曲线,而且还有许多框架和库让您也很忙。 如果您正在寻找其他资源来学习或在工作中使用,请查看Envato市场中可用的资源 。
本教程介绍了contentEditable
属性的基础知识以及如何将其用于创建基本的嵌入式文本编辑器。 下一个教程将教您如何实现工具栏并提供丰富的文本编辑功能。