创建内联编辑器需要付出努力。您首先input使用或 textarea字段切换要编辑的元素 。为了获得无缝的用户体验,您可能还必须使用一些css以使交换元素的样式与原始元素相匹配。用户完成编辑后,您将不得不在将所有内容复制到原始内容后再次切换元素。
该 contentEditable属性使这项任务变得容易得多。您所要做的就是将此属性设置为true,标准html 5 元素将变为可编辑。在本教程中,我们将基于此功能创建一个内联富文本编辑器。
基础知识
此属性可以采用三个有效值。这些true是false和inherit。该值true指示该元素是可编辑的。空字符串也将评估为真。 false表示该元素不可编辑。该值inherit是默认值。inherit指示如果元素的直接父元素是可编辑的,则该元素将是可编辑的。这意味着如果您使一个元素可编辑,那么它的所有子元素(而不仅仅是直接子元素)也将变为可编辑的,除非您将它们的contentEditable属性显式设置为false.
您可以使用javascript动态更改这些值。如果新值不是三个有效值中的任何一个,则会引发 SyntaxError 异常。
创建编辑器
要创建内联编辑器,您需要能够在 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包含我们文档中由指定选择器匹配的所有元素的 a。这样,使用一个变量就更容易跟踪可编辑元素。例如,我们的文档的标题可以通过使用来访问editables[0],这就是我们接下来要做的。
接下来,我们为按钮的单击事件添加一个事件***器。每次用户单击“编辑文档”按钮时,我们都会检查标题是否可编辑。如果它不可编辑,我们将 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 各个元素的 设置为检索到的值。
查看另一个 CodePen 演示。
使编辑器更加用户友好
为了进一步改进我们的内联编辑器,我们需要进行两项更改。第一个是明确区分什么是可编辑的,什么是不可编辑的。这可以通过使用 CSS 更改可编辑元素的外观来实现。更改相关元素的字体和颜色应该可以解决问题。只要属性设置为, [contenteditable="true"] 选择器就会将以下样式应用于元素。contenteditabletrue
[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); } });
在本教程中,我坚持使用前一种方法。您可以根据项目中似乎更合适的任何事件自由触发自动保存。
查看 CodePen 演示。
使用设计模式编辑整个页面
contentEditable当您必须编辑网页上的一些元素时非常有用。当需要更改网页上所有或几乎所有元素的内容时,可以使用该 designMode属性。此属性适用于整个文档。要转动它 on和 off,请分别使用 document.designMode = 'on';和 document.designMode = 'off';。
在您是设计师而其他人是内容创建者的情况下,这将证明是有价值的。您为他们提供设计和一些虚拟文本。稍后,他们可以用真实内容替换它。要查看 designMode 实际情况,请在浏览器的开发人员工具中打开控制台选项卡。在控制台中输入 document.designMode = 'on';并按Enter。此页面上的所有内容现在都应该是可编辑的。
最后的想法
该 contentEditable属性在快速编辑文章或使用户能够通过单击编辑他们的评论等情况下很方便。此功能首先由 IE 5.5 实现。后来,它被WHATWG标准化。浏览器支持也不错。除 Opera Mini 以外的所有主流浏览器都支持此属性。