Когда страница просто показывает текст, JavaScript почти не нужен. Он становится интересным в тот момент, когда пользователь что-то делает: нажимает кнопку, вводит имя, выбирает чекбокс, отправляет форму, двигает мышью
Все это события. А addEventListener — способ сказать браузеру: "когда произойдет вот это событие, выполни вот эту функцию"
В этом уроке соберем маленькую страницу с кнопками, полем ввода и формой. На практике разберем click, input, submit, event.target и самые частые ошибки
- Что получится в конце
- Мини-разметка
- click: обработчик кнопки
- input: реагируем на ввод
- submit: форма без перезагрузки
- event: что приходит в обработчик
- event.target: один обработчик для нескольких кнопок
- Полный script.js
- Частые ошибки
- Вызывают функцию сразу
- Забывают preventDefault у формы
- Вешают обработчик на null
- Путают target и currentTarget
- Мини-задания
- Ответы на эти вопросы могут быть для вас полезными
- Что такое событие в JavaScript?
- Что делает addEventListener?
- Почему форма перезагружается?
- Когда использовать input, а когда change?
- Зачем нужен event.target?
- Что почитать дальше по JavaScript
Что получится в конце
Мы сделаем интерактивный блок:
- кнопка увеличивает счетчик;
- поле ввода сразу показывает введенный текст;
- форма не перезагружает страницу, а выводит сообщение;
- несколько кнопок работают через один обработчик.
Это база для меню, фильтров, калькуляторов, форм и маленьких интерфейсов
Мини-разметка
Создай index.html:
<!doctype html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>События JavaScript</title>
</head>
<body>
<h1>События JavaScript</h1>
<button class="counter-button">Клик</button>
<p class="counter">Кликов: 0</p>
<input class="name-input" placeholder="Введите имя">
<p class="preview">Здесь появится имя</p>
<form class="feedback-form">
<input class="email-input" type="email" placeholder="Email">
<button type="submit">Отправить</button>
</form>
<p class="form-result"></p>
<div class="colors">
<button data-color="red">Красный</button>
<button data-color="green">Зеленый</button>
<button data-color="blue">Синий</button>
</div>
<p class="color-result">Цвет пока не выбран</p>
<script src="script.js"></script>
</body>
</html>
click: обработчик кнопки
В script.js:
const counterButton = document.querySelector(".counter-button");
const counter = document.querySelector(".counter");
let clicks = 0;
counterButton.addEventListener("click", () => {
clicks = clicks + 1;
counter.textContent = `Кликов: ${clicks}`;
});
click срабатывает, когда пользователь нажал кнопку. Мы увеличиваем переменную и обновляем текст на странице
Это самая простая модель события:
- Находим элемент.
- Добавляем слушатель.
- Внутри функции меняем страницу.
input: реагируем на ввод
Теперь сделаем живой preview имени:
const nameInput = document.querySelector(".name-input");
const preview = document.querySelector(".preview");
nameInput.addEventListener("input", () => {
preview.textContent = `Вы ввели: ${nameInput.value}`;
});
Событие input срабатывает почти сразу, когда значение поля меняется. Это удобно для:
- live-preview;
- фильтра списка;
- подсчета символов;
- проверки формы во время ввода.
Если поле пустое, можно показать запасной текст:
nameInput.addEventListener("input", () => {
if (nameInput.value === "") {
preview.textContent = "Здесь появится имя";
} else {
preview.textContent = `Вы ввели: ${nameInput.value}`;
}
});
submit: форма без перезагрузки
По умолчанию HTML-форма пытается отправиться и перезагрузить страницу. Для учебного интерфейса нам это мешает
const form = document.querySelector(".feedback-form");
const emailInput = document.querySelector(".email-input");
const formResult = document.querySelector(".form-result");
form.addEventListener("submit", (event) => {
event.preventDefault();
formResult.textContent = `Заявка для ${emailInput.value} подготовлена`;
});
event.preventDefault() отменяет стандартное поведение. В данном случае — отправку формы браузером
Это одна из первых вещей, которую нужно понять при работе с формами. Если ее забыть, страница обновится, и ты не успеешь увидеть результат
event: что приходит в обработчик
Обработчик может принимать объект события:
counterButton.addEventListener("click", (event) => {
console.log(event);
});
Внутри event много информации: какой элемент вызвал событие, где был клик, какая клавиша нажата, можно ли отменить стандартное поведение
Чаще всего на старте нужны:
event.preventDefault();event.target;event.currentTarget.
event.target: один обработчик для нескольких кнопок
У нас есть блок:
<div class="colors">
<button data-color="red">Красный</button>
<button data-color="green">Зеленый</button>
<button data-color="blue">Синий</button>
</div>
Можно повесить один обработчик на контейнер:
const colors = document.querySelector(".colors");
const colorResult = document.querySelector(".color-result");
colors.addEventListener("click", (event) => {
const button = event.target;
const color = button.dataset.color;
colorResult.textContent = `Выбран цвет: ${color}`;
});
event.target — элемент, по которому реально кликнули. Если кликнули по кнопке "Зеленый", event.target будет этой кнопкой
Но здесь есть аккуратность: если внутри контейнера появится другой элемент, у него может не быть data-color. Поэтому лучше добавить проверку:
colors.addEventListener("click", (event) => {
const button = event.target;
if (!button.dataset.color) {
return;
}
colorResult.textContent = `Выбран цвет: ${button.dataset.color}`;
});
Полный script.js
const counterButton = document.querySelector(".counter-button");
const counter = document.querySelector(".counter");
const nameInput = document.querySelector(".name-input");
const preview = document.querySelector(".preview");
const form = document.querySelector(".feedback-form");
const emailInput = document.querySelector(".email-input");
const formResult = document.querySelector(".form-result");
const colors = document.querySelector(".colors");
const colorResult = document.querySelector(".color-result");
let clicks = 0;
counterButton.addEventListener("click", () => {
clicks = clicks + 1;
counter.textContent = `Кликов: ${clicks}`;
});
nameInput.addEventListener("input", () => {
if (nameInput.value === "") {
preview.textContent = "Здесь появится имя";
} else {
preview.textContent = `Вы ввели: ${nameInput.value}`;
}
});
form.addEventListener("submit", (event) => {
event.preventDefault();
formResult.textContent = `Заявка для ${emailInput.value} подготовлена`;
});
colors.addEventListener("click", (event) => {
const button = event.target;
if (!button.dataset.color) {
return;
}
colorResult.textContent = `Выбран цвет: ${button.dataset.color}`;
});
Частые ошибки
Вызывают функцию сразу
Неправильно:
button.addEventListener("click", sayHello());
Так функция запустится сразу при загрузке страницы. В обработчик нужно передать саму функцию:
button.addEventListener("click", sayHello);
или стрелочную функцию:
button.addEventListener("click", () => {
sayHello();
});
Забывают preventDefault у формы
Если форма обновляет страницу, проверь:
event.preventDefault();
Вешают обработчик на null
Если querySelector не нашел элемент, переменная будет null. Потом:
button.addEventListener("click", () => {});
сломается. Проверь классы в HTML и порядок подключения скрипта
Путают target и currentTarget
event.target — куда именно кликнули. event.currentTarget — элемент, на котором висит обработчик. В делегировании событий эта разница важна
Мини-задания
- Добавь кнопку "Сбросить счетчик".
- Сделай preview, который показывает количество символов в поле.
- Запрети отправку формы, если email пустой.
- Добавь четвертую кнопку цвета.
- Сделай выбранный цвет фоном страницы.
Пример для фона:
document.body.style.backgroundColor = button.dataset.color;
Ответы на эти вопросы могут быть для вас полезными
Что такое событие в JavaScript?
Это сигнал о том, что что-то произошло: клик, ввод текста, отправка формы, загрузка страницы, движение мыши
Что делает addEventListener?
Он добавляет обработчик события к элементу. Когда событие происходит, браузер вызывает переданную функцию
Почему форма перезагружается?
Так работает стандартное поведение HTML-формы. Чтобы отменить его в JavaScript, используют event.preventDefault()
Когда использовать input, а когда change?
input срабатывает при каждом изменении значения. change обычно срабатывает позже, когда изменение зафиксировано. Для живого preview чаще нужен input
Зачем нужен event.target?
Он показывает, какой элемент вызвал событие. Это удобно, когда один обработчик обслуживает несколько кнопок или элементов списка
Что почитать дальше по JavaScript
Чтобы двигаться по теме без рывков, рядом лучше открыть:
- JavaScript с нуля: меняем текст на странице по клику — вернуться к самому первому примеру с кнопкой.
- If else в JavaScript: условия на живых примерах — добавить условия внутрь обработчиков событий.
- javascript:void(0): что это и почему ссылка не открывается — понять старые ссылки, которые работают через обработчики клика.
- Promise и AJAX в JavaScript: первый запрос через fetch — перейти к событиям, которые запускают запросы к серверу.



