Что такое DOM и как JavaScript меняет страницу
Основы3 минРедакция Innovialabs
Коротко
DOM — это живое дерево объектов, которое браузер строит из HTML; JavaScript находит в нём узлы, меняет их и реагирует на события, а браузер сразу перерисовывает страницу.
Что такое DOM
DOM (Document Object Model) — это представление страницы в виде дерева объектов. Браузер читает HTML и строит из него структуру: у документа есть <html>, внутри — <head> и <body>, внутри body — заголовки, абзацы, кнопки. Каждый элемент, текст и комментарий — это узел дерева.
Важно: DOM — не HTML-файл. HTML — это исходный текст, а DOM — живая модель в памяти. JavaScript меняет именно её, и браузер тут же отображает изменения. Если открыть «Просмотр кода», вы увидите исходный HTML; если открыть DevTools → Elements, вы увидите текущий DOM.
Как найти элемент
const title = document.querySelector("h1"); // первый h1
const buttons = document.querySelectorAll(".btn"); // все .btn
const form = document.getElementById("order-form");
querySelectorпринимает любой CSS-селектор и возвращает первый найденный элемент илиnull.querySelectorAllвозвращает статичный список всех совпадений.
Как изменить страницу
title.textContent = "Новый заголовок";
title.classList.add("is-active");
form.setAttribute("aria-busy", "true");
const item = document.createElement("li");
item.textContent = "Новый пункт";
document.querySelector("ul").append(item);
item.remove();
Пара правил:
- Для текста используйте textContent, а не
innerHTML. Вставка пользовательских данных черезinnerHTMLоткрывает дорогу XSS-атакам. - Стили лучше менять через классы, а не через
element.style: оформление остаётся в CSS.
События
Страница реагирует на действия пользователя через события: клик, ввод текста, отправка формы, прокрутка.
const button = document.querySelector("#buy");
button.addEventListener("click", (event) => {
console.log("Клик по", event.target);
});
form.addEventListener("submit", (event) => {
event.preventDefault(); // не перезагружать страницу
});
События всплывают: клик по кнопке сначала срабатывает на ней, потом на её родителе, потом выше — до document.
Делегирование событий
Всплытие позволяет повесить один обработчик на контейнер вместо сотни обработчиков на каждый элемент:
document.querySelector("#list").addEventListener("click", (event) => {
const button = event.target.closest("button[data-id]");
if (!button) return;
console.log("Удалить", button.dataset.id);
});
Плюсы делегирования:
- Меньше обработчиков — меньше памяти и кода.
- Работает для новых элементов: пункты, добавленные позже, обрабатываются автоматически.
Почему фреймворки прячут DOM
В маленьком скрипте прямая работа с DOM — нормально. Но в большом интерфейсе быстро начинаются проблемы:
- состояние хранится в данных и в DOM одновременно, и они расходятся;
- нужно вручную помнить, какие элементы обновить при каждом изменении;
- частые изменения вызывают лишние пересчёты раскладки (layout) и перерисовки.
React, Vue, Svelte и другие решают это декларативно: вы описываете, как интерфейс должен выглядеть при текущих данных, а фреймворк сам вычисляет минимальные изменения DOM. React для этого использует виртуальное дерево, другие — компиляцию или реактивность, но идея одна: разработчик меняет данные, а не узлы.
Частые ошибки новичков
- Искать элемент до того, как он появился. Скрипт в
<head>безdeferвыполняется раньше, чем построено body. - Читать размеры элемента и тут же менять стили в цикле — это заставляет браузер раз за разом пересчитывать раскладку.
- Вставлять ввод пользователя через
innerHTML. - Вручную менять DOM внутри компонента React или Vue: фреймворк перезапишет эти изменения.