DOM модель
Document Object Model (DOM)
Когда HTML-страница загружается в браузер, он создает объектную модель документа — DOM (Document Object Model). Проще говоря, DOM представляет структуру HTML-документа в виде дерева объектов (узлов). Каждый HTML-тег становится узлом-элементом, вложенные теги становятся дочерними узлами и т.д. Текст внутри тегов также становится отдельными узлами (текстовыми). Корневым узлом дерева является объект document, представляющий всю страницу.

DOM предоставляет программный интерфейс для работы с веб-страницей. С помощью JavaScript можно получить доступ к любому элементу страницы через DOM и изменить его содержимое, атрибуты или стили; можно создавать новые элементы и узлы, удалять существующие или перемещать их, а также реагировать на действия пользователя.
Основные операции с DOM
Рассмотрим распространённые задачи при работе с DOM и соответствующие им методы:
Поиск элементов на странице: Прежде чем изменить элемент, нужно получить к нему ссылку.
document.getElementById("id")– возвращает элемент по уникальному атрибуту id.document.querySelector("селектор")– возвращает первый элемент, соответствующий CSS-селектору (как в стилях). Например,document.querySelector(".menu li")найдёт первый элемент- внутри элемента с классом menu.
document.querySelectorAll("селектор")– возвращает список всех элементов, подходящих под селектор (статический NodeList). Например, document.querySelectorAll(“p”) вернёт коллекцию абзацев. По ней можно итерироваться (она похожа на массив). Пример:
let header = document.getElementById("main-header");
let items = document.querySelectorAll(".item");
console.log(header.innerText); // текущее содержимое заголовка
console.log("Найдено элементов:", items.length);Здесь мы нашли элемент с id “main-header” и все элементы с классом “item”.
Чтение и изменение содержимого: У DOM-узлов есть свойства для работы с их содержимым.
element.textContent– получить или изменить только текст внутри элемента (без тегов).element.innerHTML– получить или заменить HTML-код внутри элемента (включая вложенные теги).
Пример:
let title = document.getElementById("main-header");
title.textContent = "Новый заголовок"; // изменили текст заголовка
let list = document.querySelector("#user-list");
list.innerHTML = "<li>Пункт 1</li><li>Пункт 2</li>"; // вставили новый список внутрь элемента
В первом случае текст заголовка заменится на “Новый заголовок”. Во втором случае все существующие дочерние элементы #user-list удалятся и заменятся на указанные два <li>.
Изменение атрибутов и стилей: Через DOM можно менять любые атрибуты элемента (например, href у ссылок, src у изображений, value у полей ввода).
Каждый атрибут доступен как свойство объекта элемента: например, img.src = "cat.png" изменит путь картинки, link.href = "/home" изменит адрес ссылки.
Для работы со стилями существует свойство element.style, через которое можно устанавливать CSS-свойства:
let box = document.querySelector(".alert");
box.style.backgroundColor = "yellow";
box.style.fontSize = "20px";Это задаст элементу с классом alert жёлтый фон и размер шрифта 20px.
Обратите внимание: имена CSS-свойств, состоящие из двух слов (например,
background-color), преобразуются в camelCase (backgroundColor).
Управление классами: часто выгоднее манипулировать не отдельными стилями, а классами элемента (классы обычно связаны с CSS-правилами). Для этого у узла есть свойство classList:
box.classList.add("active"); // добавить класс
box.classList.remove("hidden"); // убрать класс
box.classList.toggle("highlighted"); // переключить класс (если не было – добавить, было – убрать)
Изменяя классы, мы косвенно меняем оформление элемента согласно CSS-правилам.
Создание и удаление элементов: DOM позволяет создавать новые узлы и вставлять их на страницу, а также удалять существующие.
- Создать новый элемент:
document.createElement("tagName"). Пример:let newDiv = document.createElement("div");. - Создать новый текстовый узел:
document.createTextNode("просто текст")(чаще текст вставляют через textContent сразу в элемент). - Вставить элемент в документ: нужно указать, куда вставляем:
parent.appendChild(node)– добавляет node в конец списка дочерних элементов parent.parent.insertBefore(newNode, referenceNode)– вставляетnewNodeперед указанным дочерним элементомreferenceNode.
- Удалить элемент:
parent.removeChild(node)– удаляет элемент node, являющийся дочерним для parent.Или метод самого элемента:
node.remove().
Например:
// Создадим новый абзац и добавим его в конец <body>
let paragraph = document.createElement("p");
paragraph.textContent = "Привет! Я новый абзац.";
document.body.appendChild(paragraph);
// Удалим первый элемент списка с id="user-list"
let list = document.getElementById("user-list");
let firstItem = list.querySelector("li");
list.removeChild(firstItem);В примере сначала создаётся новый <p> с текстом и добавляется на страницу. Затем из списка #user-list удаляется первый пункт.
Обработка событий: JavaScript может реагировать на различные события, происходящие на странице: клики по элементам, ввод текста, отправка формы, загрузка страницы, наведение мыши и т.д.
Для назначения обработчика события используют метод element.addEventListener(event, handler). Первый аргумент – имя события (например, “click”, “input”, “submit”), второй – функция-обработчик. Например:
let btn = document.getElementById("sendButton");
btn.addEventListener("click", function(event) {
alert("Кнопка нажата!");
});Здесь при клике по элементу с id "sendButton" выполнится функция, показывающая браузерное сообщение с текстом. Обработчик получает объект события (часто обозначается event или e), из которого можно узнать детали (например, event.target – элемент, на котором случилось событие). В данном случае в обработчике event не используется.
Существует очень много различных обработчиков событий:
keydown(нажатие клавиши),change(изменение значения поля),mouseover(курсор навёлся на элемент),mouseout(курсор ушёл) и т.д. Можно навесить несколько обработчиков на один элемент (они выполнятся в порядке добавления). Также есть старый способ – назначить обработчик через свойство, например,btn.onclick = function() { ... }, но он менее гибкий (можно назначить только один таким образом, перезаписывая предыдущий).
Комбинируя создание элементов и события, можно реализовывать динамически изменяемые интерфейсы. Например, добавим функциональность: нажатием кнопки добавлять новое поле ввода в форму (полезно для «добавить ещё один интерес» в анкете):
document.getElementById("addInterestButton").addEventListener("click", () => {
// Создаём новое поле ввода типа text
let newInput = document.createElement("input");
newInput.type = "text";
newInput.name = "interest";
newInput.placeholder = "Ваш интерес";
// Добавляем его в контейнер с id="interestList"
document.getElementById("interestList").appendChild(newInput);
});Каждый клик по кнопке с id "addInterestButton" выполнит этот код: создастся новый <input> и вставится в элемент-контейнер с id "interestList" (например, div в форме). Пользователь сможет динамически добавлять несколько интересов.
Работа с HTML формами
HTML-форма – это область страницы (<form>), предназначенная для ввода пользователя и отправки этих данных на сервер. Формы содержат интерактивные элементы: текстовые поля, выпадающие списки, флажки (checkbox), переключатели (radio), кнопки и т.д. JavaScript часто применяется для валидации (проверки) данных формы перед их отправкой, а также для улучшения UX (подсказки при вводе, динамическое добавление полей и пр.).
Пример простой формы:
<form action="/submit" method="POST">
<label for="name">Имя:</label>
<input type="text" id="name" name="name" required><br><br>
<label for="email">Email:</label>
<input type="email" id="email" name="email" required><br><br>
<label for="message">Сообщение:</label><br>
<textarea id="message" name="message" rows="4" cols="40"></textarea><br><br>
<button type="submit">Отправить</button>
</form>Здесь:
<form action="/submit" method="POST">– тег формы, атрибутactionуказывает URL (условно “/submit”), на который будут отправлены данные,method="POST"задаёт HTTP-метод. При нажатии на кнопку отправки браузер соберёт все поля и выполнит запрос по указанному адресу.<label for="name">– определяет метку для поля (при клике на текст метки курсор перейдёт в соответствующее поле). Связывание идёт через атрибутfor, который совпадает сidполя.<input type="text" id="name" name="name" required>– однострочное текстовое поле для ввода имени. Атрибут name очень важен: именно по нему это поле будет идентифицироваться на сервере. Атрибутrequiredуказывает, что поле обязательное (браузер сам проверит, что пользователь что-то ввёл, перед отправкой).<input type="email" ... required>– поле для вводаemail. Браузеры реализуют базовую проверку формата email (наличие символа @ и точки и др.).<textarea id="message" name="message">– многострочное поле для ввода произвольного текста сообщения.<button type="submit">– кнопка отправки формы. По нажатию, если скриптом не перехвачено и все обязательные поля заполнены, форма отправится наaction.
Без JavaScript при нажатии кнопки страница перезагрузится и перейдёт на адрес, указанный в action (либо этой же странице, если action не задан). Но благодаря JS можно перехватить отправку, проверить данные, вывести подсказки, и только потом вручную отправить (или отправить запрос в фоне).
Валидация и обработка данных формы с помощью JavaScript
JavaScript позволяет сделать проверку заполнения формы прямо в браузере, ещё до отправки на сервер. Это улучшает удобство: пользователь мгновенно получает сообщения об ошибках и может исправить их.
Самый распространённый подход – слушать событие submit на элементе <form>. Это событие происходит, когда пользователь пытается отправить форму (например, нажал кнопку submit). В обработчике этого события можно отменить стандартное действие и выполнить свою логику проверки.
Пример валидации формы с JavaScript:
let form = document.querySelector("form");
form.addEventListener("submit", function(event) {
event.preventDefault(); // Отключаем стандартную отправку формы
// Получаем значения полей
let name = document.getElementById("name").value.trim();
let email = document.getElementById("email").value.trim();
let message = document.getElementById("message").value.trim();
// Проверяем поля
if (name === "" || email === "" || message === "") {
alert("Пожалуйста, заполните все поля формы.");
return; // прерываем выполнение обработчика
}
if (!email.includes("@")) {
alert("Пожалуйста, введите корректный адрес email.");
return;
}
if (message.length < 10) {
alert("Сообщение слишком короткое (минимум 10 символов).");
return;
}
// Если проверки пройдены:
alert("Форма заполнена верно! Данные готовы к отправке.");
// Тут можно отправить данные на сервер вручную через fetch/AJAX или позволить форме отправиться
// form.submit(); // отправить форму традиционным способом
});В этом коде:
event.preventDefault()предотвращает переход браузера по адресу в action. Форма не будет отправлена, пока мы явно не решим.- Метод
.trim()убирает пробелы с концов введённых строк, чтобы предотвратить ситуацию, когда поле вроде не пустое, но заполнено только пробелами. - Проверки: если имя, email или сообщение пустые – показываем сообщение и выходим из функции (через return). Если в email нет символа “@” – тоже ошибка. Если сообщение короче 10 символов – сообщаем об этом.
- Если ни одна проверка не вызвала return, значит все поля заполнены корректно. Мы показываем сообщение об успехе. В реальном приложении на этом месте можно отправить данные на сервер с помощью fetch или другого способа, либо вызвать
form.submit()чтобы продолжить обычную отправку.
Таким образом, пользователь получает мгновенную обратную связь. Конечно, подобную проверку необходимо дублировать и на сервере, ведь пользователь может отключить JS или обойти страницу вовсе.
Практическое задание: Реализация формы обратной связи с валидацией
Цель: Научиться работать с формами и данными, введёнными пользователем. Освоить основные методы JavaScript для проверки данных формы.
Задание:
- Создайте форму с полями для ввода имени, email и сообщения.
- Используйте JavaScript для проверки, что все поля заполнены корректно:
- Имя не должно быть пустым.
- Email должен быть корректным.
- Сообщение должно содержать хотя бы 10 символов.
- При успешной отправке формы выведите сообщение об успешной отправке. При ошибке выведите предупреждение с указанием, что необходимо исправить.
Самостоятельное задание
Часть 1: Расширенная форма с валидацией и динамическими элементами
Пользователь вводит данные в форму, видит подсказки о количестве символов в комментарии, может добавить новые интересы через динамические поля, и после валидации данные выводятся на экран.
Форма опроса
Создайте HTML-форму для опроса, которая включает следующие элементы:
- Поле для ввода имени.
- Поле для ввода возраста.
- Переключатели (radio buttons) для выбора пола.
- Чекбоксы для указания интересов (например, спорт, музыка, кино).
- Многострочное текстовое поле для комментариев с отображением текущего количества введённых символов и лимитом в 200 символов.
- Кнопка для динамического добавления новых полей для ввода интересов.
Валидация формы
- Имя не должно быть пустым.
- Возраст должен быть числом больше 0 и не старше 120.
- Пользователь должен выбрать хотя бы один интерес.
- Комментарий не должен превышать 200 символов.
- Валидация новых полей, добавленных динамически.
Вывод данных формы
После успешной валидации формы выведите введённые данные на экран в структурированном виде:
- Имя
- Возраст
- Пол
- Интересы
- Комментарии
Добавьте кнопку для динамического добавления полей для ввода новых интересов без перезагрузки страницы.
Один из вариантов реализации:
document.getElementById("addInterest").addEventListener("click", function() {
let newInterest = document.createElement("input");
newInterest.setAttribute("type", "text");
newInterest.setAttribute("name", "interest");
newInterest.setAttribute("placeholder", "Новый интерес");
let interestList = document.getElementById("interestList");
interestList.appendChild(newInterest);
});Подсчёт символов
Реализуйте подсчёт символов в реальном времени для текстового поля комментариев и покажите пользователю, сколько символов осталось до лимита.