Як створити вбудований текстовий редактор з допомогою атрибута contentEditable

20

Від автора: Створення вбудованого текстового редактора вимагає певних зусиль. Почати можна з перемикання елемента в режим редагування з допомогою полів вводу або textarea. Щоб перемикання було плавним вам доведеться надати елементів однакові стилі. Після того, як користувач закінчив редагування, необхідно замінити весь текст і знову переключити елементи. Атрибут contentEditable сильно полегшує це завдання.

Необхідно лише задати цього атрибуту значення true, і HTML5 теги можна буде редагувати. У цьому уроці за допомогою даного атрибуту ми створимо редактор форматованого тексту.

Основи

Атрибут приймає три можливих значення: true, false і inherit. True означає, що елемент можна редагувати. Порожнє значення також розцінюється, як true. False говорить про те, що елемент не можна редагувати. За промовчанням установлено значення inherit, яке означає, що елемент можна редагувати в тому випадку, якщо його найближчий батьківського контейнера також можна відредагувати. Це означає, що якщо зробити елемент можна редагувати, то і всі його дочірні елементи, в тому числі і не найближчі, будуть також доступні для редагування. Виняток становлять дочірні елементи, у яких задано contentEditable = false.

Значення можна змінювати динамічно за допомогою JavaScript. Якщо задати некоректне значення, вискочить виняток SyntaxError.

Створюємо редактор

Щоб створити вбудований редактор, потрібно вміти змінювати значення атрибута contentEditable в будь-який час.
Під час перемикання атрибута contentEditable необхідно знати, яке значення він зберігає на даний момент. Для цього можна скористатися властивістю isContentEditable. Якщо isContentEditable повертає true, елемент знаходиться в режимі редагування і навпаки. Трохи нижче ми будемо з допомогою цієї властивості визначати стан декількох елементів в документі.

Спочатку необхідно створити кнопку для переключення у режим редагування і сам текст.

Edit Document

A Nice Heading.

Last Edited By — Monty Shokeen

Some content that needs correction.

Всі елементи, які будуть редагуватися, повинні мати свій унікальний id. Ідентифікатори допоможуть нам при збереженні змін, або коли нам потрібно буде зберегти текст для подальшої його заміни в кожному елементі. Код JS нижче редагує і зберігає зміни.

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 {
// вимикаємо режим редагування
editables[0].contentEditable = ‘false’;
editables[1].contentEditable = ‘false’;
editables[2].contentEditable = ‘false’;
// змінюємо текст і колір кнопки
editBtn.innerHTML = ‘Enable Editing’;
editBtn.style.backgroundColor = ‘#F96’;
// зберігаємо дані в localStorage
for (var i = 0; i < editables.length; i++) {
localStorage.setItem(editables.getAttribute(‘id’), editables.innerHTML);
}
}
});

Для збереження відредагованого тексту змінної можна скористатися querySelectorAll(). Даний метод повертає NodeList, в якому зберігаються всі елементи документа, задані за певним селектору. З допомогою цього методу набагато легше відстежувати редаговані елементи в однієї змінної. Наприклад, отримати доступ до заголовка документа можна за допомогою editables[0], що ми зараз і зробимо.

Тепер необхідно прив’язати до події кліка по кнопці обробник. Під час кожного кліка по кнопці користувачем ми перевіряємо заголовок на режим редагування. Якщо заголовок не можна редагувати, всім редагування елементів ми задаємо властивість contentEditable в true. А текст кнопки ‘Edit Document’ міняємо на ‘Save Changes’. Після того, як користувач вніс необхідні зміни, він клацає на кнопку ‘Save Changes’, що приводить до моментального збереження змін.

Якщо заголовок редагується, всіх елементів задається властивість contentEditable в false. На даному етапі ми може зберігати контент документа на сервері, щоб скористатися ним пізніше, а можемо синхронізувати зміни з копією документа. У цьому уроці я все буду зберігати в localStorage. Щоб випадково не перезаписати дані при збереженні в localStorage, я використовую id кожного елемента. CodePen демо

Отримання вмісту, збереженого

Якщо ви в демо вище внесете якісь зміни і перезавантажте сторінку, то всі зміни пропадуть. Це відбувається тому, що не прописаний код, який би відновлював збережені дані. Після збереження даних в 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»].

[contenteditable=»true»] {
font-family: «Rajdhani»;
color: #C00;
}

Друга зміна – автозбереження даних. Зробити це можна по-різному. Можна зберігати дані кожні 5 секунд.

setInterval(function() {
for (var i = 0; i < editables.length; i++) {
localStorage.setItem(editables.getAttribute(‘id’), editables.innerHTML);
}
}, 5000);

Можна зберігати дані по кожній події натискання.

document.addEventListener. (‘keydown’, function(e) {
for (var i = 0; i < editables.length; i++) {
localStorage.setItem(editables.getAttribute(‘id’), editables.innerHTML);
}
});

У цій статті я використовував перший метод. Ви можете зберігати дані з будь-якої події, що вважаєте потрібним. CodePen демо

Редагування всієї сторінки за допомогою властивості Design Mode

contentEditable корисний, коли потрібно змінити кілька елементів на веб-сторінці. Якщо ж вам потрібно змінити всі або майже всі елементи на сторінці, то тут вам допоможе властивість designMode. Ця властивість застосовується до всього документа. Для включення і відключення використовуються відповідно document.designMode = ‘on’; і document.designMode = ‘off’;.

Дана властивість довело свою корисність в ситуаціях, коли ви дизайнер і працюєте з контент-менеджером. Ви створюєте дизайн сторінки і заповнюєте її пробним текстом, а контент-менеджери замінюють цей текст на нормальний. Щоб подивитися designMode в дії, відкрийте консоль панелі розробника браузера, введіть document.designMode = ‘on’; і натисніть Enter. Тепер все на сторінці можна редагувати.

Заключні думки

Атрибут contentEditable зручний у тих ситуаціях, коли потрібно швидко відредагувати статтю або дозволити користувачам швидко змінити їх коментар. Вперше дана функція була реалізована в IE 5.5, пізніше вона була стандартизована в WHATWG. Підтримка в браузерах теж досить непогана. Атрибут підтримується у всіх основних браузерах, за винятком Opera Mini.

JavaScript де-факто став одним з мов роботи в інтернеті. Даний мову вимагає ретельного вивчення. Також вам можуть знадобитися різні фреймворки та бібліотеки. Якщо ви шукайте додаткові джерела для вивчення або хочете почати використовувати цю мову в своїх роботах, загляньте на Envato marketplace.

У даному уроці ви дізналися про засади атрибута contentEditable і про те, як його використовувати для створення простих вбудованих редакторів тексту. У наступному уроці ви навчитеся створювати панель інструментів і додавати різні функції в редактор.