События
Страница отвечает на действия
Всё интерактивное на сайтах — кнопки, меню, поля поиска, игры — устроено одинаково: код подписывается на событие («когда по этой кнопке кликнут…») и говорит, какую функцию тогда вызвать. Сам код при этом ничего не ждёт: программа заканчивается, а функция-обработчик срабатывает потом, когда событие случится.
addEventListener
const btn = document.querySelector("#hello");
btn.addEventListener("click", () => {
console.log("Кнопку нажали!");
});
Первый аргумент — название события, второй — функция-обработчик. Её не вызывают сами (без ()):
браузер вызовет её при каждом клике. Подписаться можно сколько угодно раз — сработают все обработчики
по порядку.
Частые события:
| Событие | Когда |
|---|---|
click |
клик мышью или касание |
input |
значение поля изменилось (каждая буква) |
change |
поле изменили и ушли из него; выбор в select, чекбокс |
submit |
отправка формы (Enter или кнопка) |
keydown / keyup |
клавиша нажата / отпущена |
mouseenter / mouseleave |
мышь зашла на элемент / ушла |
focus / blur |
поле получило / потеряло фокус |
Встречается и старый способ — btn.onclick = () => {...}. У элемента может быть только одна такая
функция, новая затирает старую, поэтому лучше addEventListener.
Состояние между событиями
Обработчик вызывается много раз, а данные между вызовами хранят в переменной снаружи обработчика:
let likes = 0;
const likeBtn = document.querySelector("#like");
likeBtn.addEventListener("click", () => {
likes++;
likeBtn.textContent = `♥ ${likes}`;
});
Если объявить let likes = 0 внутри стрелки, при каждом клике счёт начинался бы заново.
Объект события
Браузер передаёт в обработчик объект события с подробностями — обычно его называют e или event:
document.querySelector("#box").addEventListener("click", (e) => {
console.log(e.type); // "click"
console.log(e.target); // элемент, по которому кликнули
console.log(e.clientX, e.clientY); // координаты мыши в окне
});
e.target — элемент, на котором событие произошло. Это пригодится в следующей теме, когда один
обработчик будет обслуживать много кнопок.
Ввод текста
const search = document.querySelector("#search");
search.addEventListener("input", () => {
console.log("Ищем:", search.value);
});
input срабатывает на каждый символ — так делают «живой» поиск и счётчики символов. change — когда
пользователь закончил и ушёл из поля; для <select> и чекбоксов он срабатывает сразу при выборе.
Клавиатура
Нажатия клавиш слушают на document (или на поле ввода). Какая клавиша — в e.key:
document.addEventListener("keydown", (e) => {
if (e.key === "Enter") console.log("Ввод");
if (e.key === "ArrowUp") console.log("Стрелка вверх");
if (e.key === " ") console.log("Пробел");
if (e.ctrlKey && e.key === "s") console.log("Ctrl+S");
});
Названия: буквы — "a", "B"; стрелки — "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown";
"Enter", "Escape", "Shift", " " (пробел).
Отменить действие браузера
У некоторых событий есть действие по умолчанию: ссылка уводит на другую страницу, форма
перезагружает страницу, пробел прокручивает её. e.preventDefault() его отменяет:
document.querySelector("a.no-go").addEventListener("click", (e) => {
e.preventDefault();
console.log("Никуда не идём");
});
Отписаться
Чтобы обработчик перестал срабатывать, его снимают removeEventListener — с той же самой
функцией, поэтому её нужно сохранить в переменную:
const onClick = () => console.log("клик");
btn.addEventListener("click", onClick);
btn.removeEventListener("click", onClick);
// Или сразу: сработать только один раз
btn.addEventListener("click", () => console.log("первый клик"), { once: true });
Итог
el.addEventListener("событие", функция)— подписка; функцию передаём, а не вызываем.- Данные между событиями — в переменных снаружи обработчика.
e.target— где произошло,e.key— какая клавиша,e.preventDefault()— отменить действие браузера.input— каждое изменение поля,change— завершённое изменение,keydown— нажатие клавиши.