Создание встроенного редактора требует усилий. Вы начинаете с переключения редактируемого элемента с помощью поля input
или textarea
поля. Для беспроблемного взаимодействия с пользователем вам, возможно, придется использовать немного CSS, чтобы согласовать стили замененных элементов с оригинальными. Как только пользователь завершит редактирование, вам снова придется переключать элементы после копирования всего содержимого в исходное.
Атрибут contentEditable
облегчает эту задачу. Все, что вам нужно сделать, это установить для этого атрибута значение true
и стандартные элементы HTML5 станут редактируемыми. В этом уроке мы создадим встроенный текстовый редактор на основе этой функции.
Основы
Этот атрибут может принимать три допустимых значения. Это true
, false
и inherit
. Значение true
указывает, что элемент является редактируемым. Пустая строка также будет иметь значение true. false
указывает на то, что элемент недоступен для редактирования. Значение inherit
является значением по умолчанию. inherit
означает, что элемент будет редактируемым, если его непосредственный родитель является редактируемым. Это означает, что если вы сделаете элемент редактируемым, все его дочерние элементы, а не только непосредственные, также станут редактируемыми, если вы явно не установите для их атрибута contentEditable
значение false
.
Вы можете изменить эти значения динамически с помощью JavaScript. Если новое значение не является ни одним из трех допустимых, оно генерирует исключение SyntaxError .
Создание редактора
Чтобы создать встроенный редактор, вам нужно иметь возможность изменять значение атрибута contentEditable
всякий раз, когда пользователь решает что-то отредактировать.
При переключении атрибута contentEditable
необходимо знать, какое значение имеет атрибут в настоящее время. Для этого вы можете использовать свойство isContentEditable
. Если isContentEditable
возвращает true
для элемента, тогда элемент в настоящее время редактируемый, в противном случае это не так. Мы будем использовать это свойство в ближайшее время для определения состояния различных элементов в нашем документе.
Первым шагом в создании редактора является создание кнопки для переключения редактирования и некоторых редактируемых элементов.
1
2
3
4
5
6
7
|
<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
<p id=»content»>Some content that needs correction.</p>
</div>
|
Каждый элемент, который мы хотим сохранить редактируемым, должен иметь свой собственный уникальный Id
. Это будет полезно, когда нам нужно сохранить изменения или извлечь их позже, чтобы заменить текст внутри каждого элемента.
Следующий код JavaScript обрабатывает все редактирование и сохранение.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
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]
, что мы и будем делать дальше.
Затем мы добавляем прослушиватель событий в событие нажатия нашей кнопки. Каждый раз, когда пользователь нажимает кнопку «Редактировать документ», мы проверяем, можно ли редактировать заголовок. Если он не редактируется, мы устанавливаем свойство contentEditable
для каждого из редактируемых элементов в значение true
. Кроме того, текст 'Edit Document'
меняется на 'Save Changes'
. После того, как пользователи внесли некоторые изменения, они могут нажать кнопку 'Save Changes'
, и сделанные изменения могут быть сохранены навсегда.
Если заголовок редактируемый, мы устанавливаем для свойства contentEditable
каждого из редактируемых элементов значение false. На этом этапе мы также можем сохранить содержимое нашего документа на сервере для последующего извлечения или синхронизировать изменения с копией, которая существует где-то еще. В этом уроке я собираюсь сохранить все в localStorage
. При сохранении значения в localStorage
я использую Id
каждого элемента, чтобы убедиться, что я ничего не перезаписываю.
Смотрите мою живую демонстрацию CodePen .
Получение сохраненного контента
Если вы внесете изменения в любой из элементов предыдущей демонстрации и перезагрузите страницу, вы заметите, что сделанные вами изменения пропали. Это потому, что нет кода для извлечения сохраненных данных. После того, как контент был сохранен в localStorage
, мы должны извлечь его позже, когда пользователь снова заходит на веб-страницу.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
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"]
будет применять следующий стиль к элементам всякий раз, когда атрибут contenteditable
имеет значение true
.
1
2
3
4
|
[contenteditable=»true»] {
font-family: «Rajdhani»;
color: #C00;
}
|
Вторым улучшением будет возможность автоматического сохранения данных. Вы можете сделать это несколькими способами, например, автоматически сохранять каждые пять секунд.
1
2
3
4
5
|
setInterval(function() {
for (var i = 0; i < editables.length; i++) {
localStorage.setItem(editables[i].getAttribute(‘id’), editables[i].innerHTML);
}
}, 5000);
|
Вы также можете сохранить изменения для каждого события keydown
.
1
2
3
4
5
|
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
. Это свойство применимо ко всему документу. Чтобы включить и off
, вы используете document.designMode = 'on';
и document.designMode = 'off';
соответственно.
Это окажется полезным в ситуациях, когда вы дизайнер, а кто-то другой — создатель контента. Вы предоставляете им дизайн и некоторый фиктивный текст. Позже они могут заменить его реальным контентом. Чтобы увидеть designMode
в действии, откройте вкладку консоли в инструментах разработчика вашего браузера. Тип document.designMode = 'on';
в консоль и нажмите Enter . Все на этой странице должно быть доступно для редактирования.
Последние мысли
Атрибут contentEditable
удобен в ситуациях, таких как быстрое редактирование статей или предоставление пользователям возможности редактировать свои комментарии одним щелчком мыши. Эта функция была впервые реализована в IE 5.5. Позже, это было стандартизировано WHATWG. Поддержка браузера тоже довольно хорошая. Все основные браузеры, кроме Opera Mini, поддерживают этот атрибут.
JavaScript стал одним из де-факто языков работы в сети. Это не без кривых обучения, и есть множество фреймворков и библиотек, которые также могут вас занять. Если вы ищете дополнительные ресурсы для обучения или использования в своей работе, посмотрите, что у нас есть на рынке Envato .
В этом руководстве рассматриваются основы атрибута contentEditable
и его использование для создания основного встроенного текстового редактора. В следующем уроке вы узнаете, как реализовать панель инструментов и предоставить расширенные возможности редактирования текста.