document.querySelectorAll(selector): Возвращает NodeList (статическую коллекцию, похожую на массив, но не живую) всех элементов, которые соответствуют указанному CSS-селектору.javascript// Получить все параграфы
let allParagraphs = document.querySelectorAll("p");
console.log(allParagraphs); // NodeList [
…
,…
]// Получить все элементы с классом "item"
let allItems = document.querySelectorAll(".item");
console.log(allItems);
// Получить все элементы h1, h2, h3
let headings = document.querySelectorAll("h1, h2, h3");
// Получить все элементы li внутри ul
let listItems = document.querySelectorAll("ul li");
// Перебор NodeList (можно использовать forEach, for…of)
listItems.forEach((item, index) => {
console.log(`List item ${index + 1}: ${item.textContent}`);
});
Когда использовать какой метод:
getElementById: Если у вас есть id и вам нужен один конкретный элемент. Очень быстро.
querySelector: Универсальный метод для поиска первого элемента по любому CSS-селектору. Гибкий и удобный.
querySelectorAll: Для поиска всех элементов, соответствующих CSS-селектору. Возвращает NodeList, который удобно перебирать.
getElementsByTagName, getElementsByClassName: Могут быть немного быстрее querySelectorAll в специфических случаях, но querySelectorAll часто предпочтительнее из-за его универсальности и поддержки CSS-селекторов.
7.3. Изменение содержимого и атрибутов элементовПолучив доступ к элементу, мы можем изменять его содержимое, атрибуты и стили.
А) Изменение текстового содержимого:
element.textContent: Устанавливает или возвращает текст внутри элемента. HTML-теги внутри текста будут отображаться как обычный текст.
element.innerHTML: Устанавливает или возвращает HTML-код внутри элемента. Это значит, что если вы присвоите сюда строку с HTML-тегами, они будут интерпретированы браузером. Используйте с осторожностью, чтобы избежать XSS-уязвимостей (если содержимое приходит от пользователя).
html
Старый текст.
javascript
let paragraph = document.getElementById("myParagraph");
// Изменение текста
paragraph.textContent = "Новый текст."; // Отобразится как обычный текст
console.log(paragraph.textContent); // "Новый текст."
// Изменение HTML-содержимого
let div = document.getElementById("myDiv");
div.innerHTML = "Жирный текст и курсив."; // HTML-теги будут обработаны
console.log(div.innerHTML); // "Жирный текст и курсив."
// Если использовать textContent вместо innerHTML с HTML-тегами
div.textContent = "Жирный текст"; // Отобразится как "Жирный текст" (буквально)
Б) Изменение атрибутов:
Прямой доступ (для стандартных атрибутов): Если атрибут является стандартным свойством элемента (например, id, src, href, class, value), вы можете получить или установить его напрямую.html
javascriptlet img = document.getElementById("myImage");
img.src = "new_image.png"; // Изменяем источник изображения
img.alt = "Новое описание"; // Изменяем атрибут alt
let link = document.getElementById("myLink");
link.href = "https://new-example.com"; // Изменяем ссылку
link.textContent = "Перейти на новый сайт"; // Изменяем текст ссылки
Методы getAttribute(), setAttribute(), removeAttribute(): Более универсальные методы, которые работают с любыми атрибутами, включая пользовательские (data-*).html
javascriptlet button = document.querySelector('button');
// Получить атрибут
console.log(button.getAttribute('data-action')); // "save"
console.log(button.getAttribute('disabled')); // null (если атрибута нет)
// Установить атрибут
button.setAttribute('disabled', ''); // Делаем кнопку неактивной (значение атрибута может быть пустым)
button.setAttribute('data-action', 'delete'); // Изменяем атрибут
// Удалить атрибут
button.removeAttribute('disabled');
В) Изменение стилей:
Стили элемента можно изменять через его свойство style. Каждый CSS-свойство, написанное через дефис (например, background-color), преобразуется в camelCase (например, backgroundColor) для использования в JavaScript.
html
javascript
let box = document.getElementById("myBox");
// Изменение стиля
box.style.width = "200px"; // Устанавливаем ширину
box.style.height = "150px"; // Устанавливаем высоту
box.style.backgroundColor = "lightgreen"; // Устанавливаем фоновый цвет
box.style.border = "2px solid red"; // Добавляем рамку
// Получение текущего стиля (может быть сложнее, чем кажется, если стили заданы в CSS-файлах, а не инлайново)
console.log(box.style.width); // "200px" (если был инлайново задан или последний измененный)
Работа с классами CSS:
Часто гораздо удобнее управлять стилями, добавляя или удаляя CSS-классы, чем менять отдельные свойства style. Это позволяет отделять логику JavaScript от стилизации.
element.classList: Это свойство возвращает объект DOMTokenList, который имеет удобные методы для управления классами:add(className): Добавляет класс.
remove(className): Удаляет класс.
toggle(className): Добавляет класс, если его нет, и удаляет, если он есть.
contains(className): Проверяет, есть ли у элемента указанный класс (возвращает true или false).
html
javascript
let divWithClass = document.getElementById("myDivWithClass");
// Добавить класс
divWithClass.classList.add("highlight"); // Класс "highlight" будет добавлен
console.log(divWithClass.className); // "box normal highlight"
// Удалить класс
divWithClass.classList.remove("normal"); // Класс "normal" будет удален
console.log(divWithClass.className); // "box highlight"
// Переключить класс
divWithClass.classList.toggle("active"); // Класс "active" будет добавлен
divWithClass.classList.toggle("active"); // Класс "active" будет удален
console.log(divWithClass.classList.contains("highlight")); // true
console.log(divWithClass.classList.contains("normal")); // false
CSS, который будет работать с этими классами:
css
.box {
width: 100px;
height: 50px;
border: 1px solid black;
}
.highlight {
background-color: yellow;
font-weight: bold;
}
.active {
border-color: blue;
transform: scale(1.1); /* Небольшое увеличение */
}
7.4. Создание и удаление элементовJavaScript может не только изменять существующие элементы, но и создавать новые, а также удалять их из DOM.
Создание элемента:
document.createElement(tagName): Создает новый элемент с указанным именем тега. Этот элемент пока не находится на странице, он существует только в памяти.javascriptlet newParagraph = document.createElement("p"); // Создали элемент
newParagraph.textContent = "Это новый параграф, созданный JavaScript.";
newParagraph.classList.add("info-text"); // Добавили класс
Добавление элемента на страницу:
Чтобы созданный элемент появился на странице, его нужно добавить к какому-либо существующему элементу.
parentElement.appendChild(childElement): Добавляет childElement как последнего потомка parentElement.javascript// Предположим, у нас есть
let container = document.getElementById("container");
let newParagraph = document.createElement("p");
newParagraph.textContent = "Добавлен в конец контейнера.";
container.appendChild(newParagraph); // Параграф появится внутри div#container
parentElement.insertBefore(newElement, referenceElement): Вставляет newElement перед referenceElement внутри parentElement.javascript// Предположим, у нас есть
Существующий
let container = document.getElementById("container");
let existingPara = document.getElementById("existingPara");
let newPara = document.createElement("p");
newPara.textContent = "Добавлен перед существующим.";
container.insertBefore(newPara, existingPara); // Новый параграф появится перед existingPara
Удаление элемента:
element.remove(): Удаляет элемент из DOM.javascriptlet elementToRemove = document.getElementById("itemToDelete");
if (elementToRemove) { // Важно проверять, существует ли элемент, прежде чем удалять
elementToRemove.remove();
}
parentElement.removeChild(childElement): Более старый метод, который удаляет childElement из parentElement.javascriptlet parent = document.getElementById("parent");
let child = document.getElementById("child");
if (parent && child) {
parent.removeChild(child);
}
7.5. Работа с классами CSS (краткое повторение)Мы уже видели classList для добавления, удаления и переключения классов. Это наиболее рекомендуемый способ управления стилями элемента с помощью JavaScript.
Пример 7.5.1: Динамическое изменение стиля кнопки
html
css
.btn {
padding: 10px 20px;
border: 1px solid gray;
background-color: lightgray;
cursor: pointer;
}
.btn.active { /* Стиль для активной кнопки */
background-color: dodgerblue;
color: white;
font-weight: bold;
}
javascript
let button = document.getElementById("myButton");
button.addEventListener("click", function() { // Добавим обработчик события клика (об этом позже)
button.classList.toggle("active"); // Переключит класс 'active' при каждом клике
});
При каждом нажатии на кнопку будет добавляться или удаляться класс active, что будет менять ее внешний вид согласно CSS-правилам.
Практическое задание:
Создайте простую HTML-страницу с
,
и
- .Используйте document.getElementById() для доступа к
- в
- и измените его textContent.
- в
- и добавьте им класс list-item с помощью forEach() и element.classList.add().
- с заданным текстом и добавляет его в конец существующего
- на странице.
- Элемент 1
- Элемент 2
- Элемент 3
- )
// event.currentTarget – это сам
- , к которому прикреплен обработчик
// event.target.tagName вернет "LI" (в верхнем регистре)
if (event.target && event.target.tagName === "LI") {
console.log('Нажали на: ' + event.target.textContent);
// Можно добавить изменения стиля, например:
// event.target.style.textDecoration = 'line-through';
}
});
Преимущества делегирования:
Производительность: Меньше обработчиков висит на странице.
Динамические элементы: Если вы добавляете новые элементы
- на страницу динамически (через JavaScript), на них автоматически будет распространяться обработчик родительского элемента, без необходимости вешать новый обработчик на каждый элемент.8.5. preventDefault и stopPropagation
Иногда нам нужно контролировать стандартное поведение браузера или остановить распространение события.
event.preventDefault(): Отменяет стандартное действие браузера, связанное с событием.Пример 8.5.1: Отмена отправки формыhtml
// Проверяем, действительно ли кликнули по элементу
Создайте элемент
с текстом “Этот параграф будет удален”. Добавьте его на страницу. Затем найдите этот параграф по его textContent (это можно сделать, например, через document.querySelectorAll('p') и цикл, или если у него есть ID) и удалите его с помощью element.remove().
Эта глава заложила основу для взаимодействия JavaScript с веб-страницей. Мы научились находить элементы, изменять их содержимое, атрибуты и стили, а также создавать и удалять элементы. Это критически важный навык для любого веб-разработчика.
В следующей главе мы углубимся в то, как JavaScript реагирует на действия пользователя – мы будем изучать события.
Глава 8: Реакция на Действия: События.
Мы научились находить элементы на веб-странице и изменять их. Но что делает веб по-настоящему захватывающим, так это интерактивность – способность страницы реагировать на то, что делает пользователь. Щелчки мыши, нажатия клавиш, движение курсора, отправка форм, загрузка страницы – все это события.
Термин: Событие (Event) – это сигнал, который генерируется системой (браузером, операционной системой, пользовательским агентом) в ответ на определенное действие. JavaScript может “слушать” эти сигналы и выполнять определенный код в ответ.
8.1. Что такое событияБраузер постоянно генерирует события. Основные типы событий, с которыми мы будем работать:
События мыши:click: Нажатие левой кнопки мыши по элементу.
dblclick: Двойной щелчок левой кнопкой мыши.
mousedown: Нажатие кнопки мыши (любой) над элементом.
mouseup: Отпускание кнопки мыши (любой) над элементом.
mousemove: Движение мыши над элементом.
mouseover: Курсор мыши вошел в область элемента.
mouseout: Курсор мыши покинул область элемента.
События клавиатуры:keydown: Нажатие клавиши.
keyup: Отпускание клавиши.
keypress: Нажатие клавиши (устарел, используется keydown или input).
События формы:submit: Отправка формы.
change: Изменение значения элемента формы (input, select, textarea), когда он теряет фокус.
input: Изменение значения элемента формы, происходит мгновенно при каждом вводе.
focus: Элемент получил фокус.
blur: Элемент потерял фокус.
События документа и окна:load: Полная загрузка страницы (все ресурсы, включая изображения, скрипты, стили, загружены).
DOMContentLoaded: DOM-дерево построено, но ресурсы (картинки, стили) могут еще загружаться. Часто используется для запуска скриптов, которые работают с DOM, так как DOM уже готов.
resize: Изменение размера окна браузера.
scroll: Прокрутка страницы.
8.2. Как реагировать на события: Обработчики событий (addEventListener)Самый современный и рекомендуемый способ “слушать” события – это метод addEventListener(). Он позволяет прикрепить одну или несколько функций-обработчиков к конкретному событию на конкретном элементе.
Термин: Обработчик события (Event Handler) – это функция, которая будет вызвана, когда произойдет определенное событие.
Синтаксис: element.addEventListener(eventType, handlerFunction, options);
element: Элемент, на котором мы хотим “слушать” событие (например, document.getElementById('myButton')).
eventType: Строка, имя события, которое мы хотим отслеживать (например, 'click', 'keydown', 'mouseover').
handlerFunction: Функция, которая будет вызвана, когда событие произойдет.
options (необязательный): Объект с дополнительными настройками (например, capture для фазы распространения события, once для однократного срабатывания, passive для оптимизации прокрутки).
Пример 8.2.1: Обработка клика по кнопке
html
javascript
let button = document.getElementById('myBtn');
button.addEventListener('click', function() {
console.log("Кнопка была нажата!");
alert("Вы нажали на кнопку!");
});
При каждом клике на кнопку myBtn будет выведено сообщение в консоль и появилось бы всплывающее окно.
Пример 8.2.2: Обработка ввода в поле формы
html
javascript
let inputField = document.getElementById('myInput');
let outputParagraph = document.getElementById('output');
// Используем событие 'input', которое срабатывает каждый раз при изменении значения
inputField.addEventListener('input', function() {
let currentValue = inputField.value; // .value – свойство поля ввода, хранящее его текущее значение
outputParagraph.textContent = "Вы вводите: " + currentValue;
});
Когда пользователь набирает текст в поле ввода, параграф output будет мгновенно обновляться.
Отмена обработчика:
Метод removeEventListener() используется для удаления обработчика, который был ранее добавлен с помощью addEventListener(). Для этого необходимо, чтобы функция-обработчик была доступна (обычно это делается путем объявления ее отдельно, а не как анонимную функцию прямо в addEventListener).
javascript
function handleClick() {
console.log("Обработчик клика сработал.");
}
let myButton = document.getElementById('myBtn');
myButton.addEventListener('click', handleClick);
// Позже, если нужно удалить обработчик:
// myButton.removeEventListener('click', handleClick);
Старые методы (не рекомендуются для нового кода):
Ранее использовались HTML-атрибуты (onclick="myFunction()") или прямое присваивание свойств (element.onclick = myFunction;). Эти методы имеют ограничения:
Позволяют прикрепить только один обработчик на событие.
Могут конфликтовать с другими скриптами, которые пытаются установить свой обработчик. addEventListener позволяет прикрепить несколько обработчиков, которые будут выполняться последовательно.
8.3. Объект события (Event Object)Когда происходит событие, браузер создает специальный объект события (Event Object), который содержит подробную информацию о событии. Этот объект автоматически передается в функцию-обработчик как первый аргумент.
javascript
let myElement = document.getElementById('someElement');
myElement.addEventListener('click', function(event) {
console.log(event); // Выведет объект события
// event содержит информацию о том, что произошло
});
Полезные свойства объекта события:
event.target: Ссылка на элемент, который ИНИЦИИРОВАЛ событие. Это может быть не тот элемент, на котором мы “слушаем” событие, если используется всплытие.
event.currentTarget: Ссылка на элемент, к которому прикреплен текущий обработчик.
event.type: Тип события (например, 'click', 'mousemove').
event.clientX, event.clientY: Координаты курсора мыши относительно видимой области окна (viewport) в момент события.
event.pageX, event.pageY: Координаты курсора мыши относительно всего документа (включая прокрученную часть).
event.key: Нажатая клавиша (для событий клавиатуры, например, 'Enter', 'a', 'ArrowRight').
event.keyCode / event.which: Код нажатой клавиши (устаревшие, лучше использовать event.key).
event.target.value: Для элементов формы – текущее значение поля.
Пример 8.3.1: Получение координат мыши и информации о клавише
html
Двигайте мышью здесь
javascript
let mouseInfoDiv = document.getElementById('mouseInfo');
let keyInfoPara = document.getElementById('keyInfo');
mouseInfoDiv.addEventListener('mousemove', function(event) {
// event.clientX и event.clientY – координаты относительно окна браузера
let x = event.clientX;
let y = event.clientY;
mouseInfoDiv.textContent = `Мышь: X=${x}, Y=${y}`;
});
document.addEventListener('keydown', function(event) { // Слушаем событие на всем документе
keyInfoPara.textContent = `Нажата клавиша: ${event.key} (код: ${event.code})`; // event.code – более современный идентификатор клавиши
});
8.4. Всплытие и погружение событий (Event Bubbling & Capturing)Когда событие происходит на одном элементе, оно не остается “привязанным” только к нему. События в DOM проходят через два этапа:
Фаза погружения (Capturing Phase): Событие “спускается” от корневого элемента документа (window или document) вниз, к целевому элементу.
Фаза всплытия (Bubbling Phase): Событие “всплывает” от целевого элемента вверх, к корневому элементу документа.
Термин: Всплытие (Event Bubbling) – процесс, при котором событие, инициированное на внутреннем элементе, последовательно “всплывает” по цепочке родительских элементов, запуская обработчики на каждом из них.
Термин: Погружение (Event Capturing) – процесс, обратный всплытию. Событие сначала проходит через родительские элементы (двигаясь сверху вниз), а затем достигает целевого элемента.
По умолчанию, addEventListener прикрепляет обработчик к фазе всплытия. Вы можете указать третьему параметру options, чтобы прикрепить обработчик к фазе погружения ({ capture: true }).
Почему это важно?
Понимание всплытия помогает объяснить, почему обработчик может сработать не только на том элементе, к которому он прикреплен, но и на его родителях. Это свойство активно используется для делегирования событий.
Термин: Делегирование событий (Event Delegation) – мощная техника, когда вместо того, чтобы вешать обработчики на множество одинаковых дочерних элементов, мы вешаем один обработчик на их общего родителя. Внутри этого обработчика мы проверяем, на каком именно дочернем элементе произошло событие (используя event.target), и выполняем нужные действия.
Пример 8.4.1: Делегирование событий для списка
html
Без делегирования (плохой подход, если элементов много):
javascript
// const listItems = document.querySelectorAll('#myList li');
// listItems.forEach(item => {
// item.addEventListener('click', function() {
// console.log('Нажали на: ' + this.textContent);
// });
// });
// Если добавить новый элемент после загрузки страницы, на него уже не будет обработчика!
С делегированием (лучший подход):
javascript
let list = document.getElementById('myList');
list.addEventListener('click', function(event) {
// event.target – это элемент, на котором произошло событие (например,
Создайте кнопку и
с id myBox, который имеет начальный стиль (цвет фона, размеры) через CSS.При нажатии на кнопку, используя addEventListener (которое мы рассмотрим позже), измените цвет фона div на случайный. Для генерации случайного цвета используйте Math.random() для RGB-компонентов.Напишите функцию createListItem(text), которая создает новый элемент
- с заданным текстом и добавляет его в конец существующего
Используйте document.querySelectorAll() для получения всех
- в
и измените его текст.
Используйте document.querySelector() для доступа к первому






