Навіщо взагалі писати редактор самому

Здавалося б, навіщо? Є TinyMCE, Quill, CKEditor — готові рішення, які підключаються за п'ять хвилин. Але у власноруч написаного редактора є своя цінність, і не лише навчальна. Наприклад, власний простий онлайн редактор може бути частиною певного проекту - його можна адаптувати під конкретні потреби користувача на певному робочому місці. Ну а для тих хто навчається теж корисно - можна побачити одразу результат зробивши щось корисне.

Крім того ви точно знаєте, що в ньому відбувається. Жодних зайвих залежностей, жодного раптового оновлення, яке зламає вам форму введення. По-друге, для невеликих проєктів — блогів, нотаток, внутрішніх інструментів — повноцінна бібліотека часто є надмірністю. І по-третє, це просто корисна вправа: ви торкаєтесь DOM, подій, localStorage, роботи з виділенням тексту — усього того, що є основою сучасного фронтенду. Як результат:

  • розумієте, як браузер працює з редагованим вмістом;
  • практикуєте роботу з подіями та DOM-маніпуляціями;
  • отримуєте готовий інструмент, який можна вбудувати в будь-який проєкт;
  • вчитеся налагоджувати та вдосконалювати власний код.

Що ми будуємо

Наш редактор матиме панель із кнопками форматування (жирний, курсив, підкреслення, заголовки), поле для введення тексту та кнопку збереження в localStorage. Нічого зайвого — лише те, що справді потрібне для роботи.

Що таке contenteditable і чому це важливо
Атрибут contenteditable="true" — це вбудований механізм браузера, який дозволяє будь-якому HTML-елементу стати редагованим. Коли ви встановлюєте цей атрибут на div, користувач може клікнути в нього і почати вводити текст, як у звичайному текстовому полі. При цьому зберігається вся HTML-структура: теги, форматування, вкладені елементи. Саме на цьому механізмі побудовані більшість WYSIWYG-редакторів у браузері.

Крок 1. HTML-структура

Починаємо з розмітки. Нам потрібна панель інструментів і область редагування. Все просто:

<!DOCTYPE html>
<html lang="uk">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <title>Простий веб-редактор</title>
 <link rel="stylesheet" href="style.css">
</head>
<body>
 <div class="editor-wrapper">
 <div class="toolbar">
 <button data-cmd="bold" title="Жирний">Ж</button>
 <button data-cmd="italic" title="Курсив">К</button>
 <button data-cmd="underline" title="Підкреслення">П</button>
 <button data-cmd="formatBlock" data-val="h2" title="Заголовок">H2</button>
 <button data-cmd="formatBlock" data-val="p" title="Звичайний текст">P</button>
 <button data-cmd="insertUnorderedList" title="Список">UL</button>
 <button id="saveBtn">Зберегти</button>
 </div>
 <div class="editor" id="editor" contenteditable="true">
 <p>Почніть вводити текст тут...</p>
 </div>
 </div>
 <script src="editor.js"></script>
</body>
</html>

Зверніть увагу на атрибут data-cmd — він зберігає команду, яку ми передамо в JavaScript. Це дозволяє уникнути купи окремих обробників для кожної кнопки.

Крок 2. Стилі CSS

Редактор має виглядати як редактор, а не як порожній блок на сторінці. Мінімальні стилі, які вже дають відчуття інструменту:

* {
 box-sizing: border-box;
 margin: 0;
 padding: 0;
}

body {
 font-family: Arial, sans-serif;
 background: #f0f2f5;
 display: flex;
 justify-content: center;
 padding: 40px 20px;
}

.editor-wrapper {
 width: 100%;
 max-width: 800px;
 background: #fff;
 border-radius: 8px;
 box-shadow: 0 2px 12px rgba(0,0,0,0.1);
 overflow: hidden;
}

.toolbar {
 display: flex;
 flex-wrap: wrap;
 gap: 6px;
 padding: 10px 14px;
 background: #f8f9fa;
 border-bottom: 1px solid #e0e0e0;
}

.toolbar button {
 padding: 6px 12px;
 border: 1px solid #ccc;
 border-radius: 4px;
 background: #fff;
 cursor: pointer;
 font-size: 14px;
 transition: background 0.2s;
}

.toolbar button:hover {
 background: #e8e8e8;
}

#saveBtn {
 margin-left: auto;
 background: #4a90e2;
 color: #fff;
 border-color: #4a90e2;
}

#saveBtn:hover {
 background: #357abd;
}

.editor {
 min-height: 400px;
 padding: 20px 24px;
 font-size: 16px;
 line-height: 1.7;
 outline: none;
 color: #333;
}

.editor h2 {
 margin: 16px 0 8px;
 font-size: 22px;
}

.editor p {
 margin-bottom: 10px;
}

.editor ul {
 padding-left: 24px;
 margin-bottom: 10px;
}

Крок 3. JavaScript — логіка редактора

Тепер найцікавіше. Браузер має вбудований метод document.execCommand(), який виконує команди форматування для редагованих елементів. Так, технічно він вважається застарілим, але досі чудово працює в усіх браузерах і є ідеальним для навчальних цілей.

const editor = document.getElementById('editor');
const saveBtn = document.getElementById('saveBtn');
const toolbarBtns = document.querySelectorAll('.toolbar button[data-cmd]');

// Обробка кнопок форматування
toolbarBtns.forEach(btn => {
 btn.addEventListener('click', () => {
 const cmd = btn.dataset.cmd;
 const val = btn.dataset.val || null;
 document.execCommand(cmd, false, val);
 editor.focus();
 });
});

// Збереження в localStorage
saveBtn.addEventListener('click', () => {
 localStorage.setItem('editorContent', editor.innerHTML);
 alert('Збережено.');
});

// Завантаження збереженого контенту
window.addEventListener('load', () => {
 const saved = localStorage.getItem('editorContent');
 if (saved) {
 editor.innerHTML = saved;
 }
});

Декілька речей, на які варто звернути увагу. Після виклику execCommand ми повертаємо фокус у поле редактора — без цього кнопки "заберуть" фокус і форматування не застосується. Метод localStorage.setItem зберігає HTML-рядок, тому після перезавантаження сторінки весь вміст із форматуванням відновлюється.

Найважливіше в написанні власних інструментів — не намагатися одразу зробити все ідеально. Спочатку зробіть щось, що просто працює. Потім покращуйте. Саме так і виглядає реальна розробка.

Крок 4. Збираємо все разом і перевіряємо

На цьому етапі у вас вже є три файли: index.html, style.css та editor.js. Відкрийте index.html у браузері — редактор повинен працювати. Введіть текст, виділіть частину і натисніть "Ж" — текст стане жирним. Натисніть "Зберегти", перезавантажте сторінку — текст залишиться.

Якщо щось не працює, перше, що варто зробити — відкрити консоль браузера (F12) і подивитися на помилки. Найчастіша причина — помилка в шляху до файлу скрипта або CSS.

Як покращити редактор і що можна додати

Базова версія готова, але це лише початок. Редактор можна розвивати в багатьох напрямках, залежно від того, які навички ви хочете прокачати.

Додаткові кнопки форматування

Легко додати вирівнювання тексту, колір шрифту або виділення фону. Наприклад, для вирівнювання по центру достатньо додати кнопку з data-cmd="justifyCenter". Для кольору шрифту — data-cmd="foreColor" із відповідним значенням кольору.

Лічильник символів

Корисна дрібниця, яку просто реалізувати. Додайте елемент під редактором і слухайте подію input:

editor.addEventListener('input', () => {
 const text = editor.innerText;
 document.getElementById('counter').textContent =
 `Символів: ${text.length}`;
});

Експорт у текстовий файл

Ще одна зручна функція — можливість завантажити текст як файл:

document.getElementById('exportBtn').addEventListener('click', () => {
 const blob = new Blob([editor.innerHTML], { type: 'text/html' });
 const a = document.createElement('a');
 a.href = URL.createObjectURL(blob);
 a.download = 'document.html';
 a.click();
});

Скасування та повтор дій

Браузер вже підтримує Ctrl+Z для скасування в contenteditable-елементах, але якщо ви хочете власну реалізацію — зберігайте стани редактора в масив і відновлюйте їх за потреби. Це трохи складніше, але дуже корисна вправа для розуміння роботи зі станом.

Серверне збереження

Якщо ви вже знайомі з базовим бекендом, можна додати збереження через fetch на сервер. Це відразу виводить редактор на новий рівень — вміст не зникне при очищенні браузера.

  1. Додайте кнопку "Зберегти на сервері".
  2. Відправляйте editor.innerHTML через fetch методом POST.
  3. На сервері збережіть у файл або базу даних.
  4. При завантаженні сторінки отримуйте збережений вміст через GET-запит.

Ось і весь шлях від порожнього файлу до працюючого редактора, який ви розумієте від першого рядка до останнього. Такий проєкт — чудовий старт для портфоліо початківця, бо він невеликий, але показує розуміння роботи з DOM, подіями і браузерним API. А якщо ви вирішите піти далі — вивчіть, як влаштовані бібліотеки Quill або Tiptap: там ті самі принципи, але реалізовані значно гнучкіше. Спробуйте додати до редактора хоча б одну нову функцію і розкажіть у коментарях, що у вас вийшло і з чим виникли труднощі.

Рубрика «ОСВІТА»
2026-03-30 • Перегляди [ 131 ]

Оцінка - 5.0 (1)

 Схожі публікації