Урок 3 из 8 · 25 мин · обновлено

JavaScript в браузере: элементы страницы и события

Как JavaScript оживляет страницу: DOM, поиск элементов, обработчики событий, изменение текста и классов. Делаем корзину кофейни, которая пересчитывает сумму.

DOM: страница как дерево

Когда браузер загружает HTML, он строит из него DOM (Document Object Model) — дерево объектов. У каждого тега свой объект: у карточки, заголовка, кнопки. JavaScript может найти любой объект и изменить его, а браузер тут же перерисует страницу.

Найти элемент помогает querySelector — он принимает тот же селектор, что и CSS:

JavaScript
const total = document.querySelector('.cart-total');
total.textContent = '470 ₽';

На странице сумма в корзине сразу станет «470 ₽».

События

Интерфейс отвечает на действия пользователя — события: нажатие (click), ввод текста (input), отправку формы (submit). Чтобы что-то произошло, на событие подписываются функцией-обработчиком:

JavaScript
const button = document.querySelector('.drink button');

button.addEventListener('click', () => {
  console.log('Нажали «В корзину»');
});
Результат
Нажали «В корзину»

Сообщение появится в консоли браузера при каждом нажатии.

Корзина кофейни

Соберём простую корзину «Зерна». В HTML у каждой кнопки есть цена в атрибуте:

HTML
<button data-price="220">Капучино — в корзину</button>
<button data-price="250">Латте — в корзину</button>
<p>В корзине: <span class="count">0</span> шт., <span class="sum">0</span> ₽</p>

JavaScript хранит состояние корзины в переменных и обновляет страницу из них:

JavaScript
let count = 0;
let sum = 0;

document.querySelectorAll('[data-price]').forEach(button => {
  button.addEventListener('click', () => {
    count += 1;
    sum += Number(button.dataset.price);
    document.querySelector('.count').textContent = count;
    document.querySelector('.sum').textContent = sum;
  });
});

Нажали «Капучино» и «Латте» — на странице появится:

Результат
В корзине: 2 шт., 470 ₽

Обратите внимание на порядок: сначала меняем данные (count, sum), потом показываем их на странице. Когда интерфейс становится сложнее, этот принцип спасает от путаницы — и именно на нём построены фреймворки из урока 6.

Классы для состояний

Часто нужно не поменять текст, а показать или спрятать элемент: например, кнопку «Оформить заказ» показывать только в непустой корзине. Удобно переключать класс, а внешний вид оставить в CSS:

JavaScript
document.querySelector('.cart').classList.toggle('is-empty', count === 0);
CSS
.cart.is-empty .checkout { display: none; }

Консоль — первый помощник

Если что-то не работает, откройте инструменты разработчика (клавиша F12) и вкладку Console. Ошибка будет выглядеть так:

Результат
Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')
    at main.js:3

Это значит: в строке 3 querySelector ничего не нашёл и вернул null. Чаще всего — опечатка в селекторе или скрипт запустился раньше, чем загрузилась разметка. Основы языка подробно разобраны в курсе «Основы JavaScript».

Попробуйте сами. Добавьте в корзину «Зерна» кнопку «Очистить», которая обнуляет количество и сумму на странице.

Пример ответа
HTML
<button class="clear">Очистить</button>
JavaScript
document.querySelector('.clear').addEventListener('click', () => {
  count = 0;
  sum = 0;
  document.querySelector('.count').textContent = count;
  document.querySelector('.sum').textContent = sum;
});

Строки обновления страницы теперь повторяются в двух местах. Их стоит вынести в отдельную функцию render() и вызывать после любого изменения корзины.

Мини-тест · 4 вопроса

Проверьте себя

Выберите вариант, который кажется вам правильным. В конце вы увидите свой результат и объяснение к каждому вопросу.

  1. Что такое DOM?

  2. Что делает addEventListener('click', ...)?

  3. Почему кнопки лучше скрывать и показывать через классы, а не менять стили прямо в JavaScript?

  4. Кнопка перестала работать. Куда посмотреть в первую очередь?