DOM создание и изменение элементов
JavaScript позволяет программно создавать новые DOM-узлы, вставлять их в документ, изменять содержимое и удалять элементы — это основа динамических пользовательских интерфейсов.
Зачем нужно
Без умения динамически изменять DOM невозможно реализовать ни один современный UI: список задач, корзину интернет-магазина, ленту новостей или уведомления. Понимание методов вставки и удаления позволяет строить эффективные компоненты без перерисовки всей страницы.
Где используется
- Добавление карточек, строк таблицы, пунктов списка из данных API
- Показ/скрытие всплывающих уведомлений и модальных окон
- Динамические формы (добавление/удаление полей)
- Рендеринг шаблонов на клиенте
- SPA-фреймворки под капотом используют те же принципы
Основной контент
Создание элементов
// Создать новый элемент
const li = document.createElement('li');
li.textContent = 'Новый пункт';
li.className = 'list-item';
li.setAttribute('data-id', '42');
// Создать текстовый узел
const text = document.createTextNode('Текст');
Вставка в DOM
const list = document.querySelector('ul');
// В конец
list.append(li); // принимает элементы и строки
list.appendChild(li); // только узлы, старый API
// В начало
list.prepend(li);
// Перед/после конкретного элемента
const existingItem = list.querySelector('.item');
existingItem.before(li); // вставить перед
existingItem.after(li); // вставить после
// Вставить несколько сразу
list.append(li1, li2, li3);
list.append('Текст', li);
insertAdjacentHTML — вставка HTML-строки
const container = document.querySelector('.container');
container.insertAdjacentHTML('beforeend', '<p class="note">Примечание</p>');
container.insertAdjacentHTML('afterbegin', '<h2>Заголовок</h2>');
container.insertAdjacentHTML('beforebegin', '<hr>');
container.insertAdjacentHTML('afterend', '<footer>...</footer>');
Позиции: beforebegin (до элемента), afterbegin (в начало), beforeend (в конец), afterend (после элемента).
Изменение содержимого
const el = document.querySelector('.card');
el.textContent = 'Только текст, HTML-теги экранируются';
el.innerHTML = '<strong>Жирный</strong> текст'; // осторожно с XSS
el.outerHTML = '<div class="new-card">замена</div>'; // заменяет сам элемент
Удаление элементов
const item = document.querySelector('.old-item');
item.remove(); // современный способ
// Через родителя — старый API
item.parentNode.removeChild(item);
Клонирование
const template = document.querySelector('.card');
const copy = template.cloneNode(true); // true — глубокое клонирование (с детьми)
copy.querySelector('.title').textContent = 'Новая карточка';
document.querySelector('.grid').append(copy);
DocumentFragment — батчевая вставка
// Избегаем многократных перерисовок
const fragment = document.createDocumentFragment;
for (let i = 0; i < 100; i++) {
const li = document.createElement('li');
li.textContent = `Элемент ${i}`;
fragment.append(li);
}
document.querySelector('ul').append(fragment); // одна вставка в DOM
Частые ошибки
- Используют
innerHTML +=— это сериализует и пересоздаёт весь DOM внутри элемента, теряются обработчики событий. ИспользуйтеappendилиinsertAdjacentHTML. - Вставляют пользовательский ввод через
innerHTML— XSS-уязвимость. Всегда используйтеtextContentдля пользовательских данных. - Вставляют 1000 элементов по одному — каждая вставка вызывает reflow. Собирайте через
DocumentFragmentилиinsertAdjacentHTMLв одну операцию. - Обращаются к элементу после
remove— ссылка на объект остаётся, но он вне DOM. Проверяйтеel.isConnectedпри необходимости.