Події — частина 1
JavaScript події — палець натискає дверний дзвінок очікуючи реакцію
У попередніх уроках ми навчилися знаходити елементи та змінювати DOM. Але поки наш код виконується одразу при завантаженні сторінки. А як зробити так, щоб щось відбувалося при кліку на кнопку або при наведенні миші? Для цього існують події.
Що таке подія?
Подія — це сигнал від браузера, що щось сталося. Користувач клікнув, навів мишу, натиснув клавішу, прокрутив сторінку — кожна з цих дій створює подію.
JavaScript може слухати події та виконувати код у відповідь. Функцію, яка виконується при події, називають обробником (handler).
addEventListener — додавання обробника
Основний спосіб реагувати на події:
const button = document.querySelector(".btn");
button.addEventListener("click", function () {
console.log("Кнопку натиснули!");
});
Синтаксис: element.addEventListener(типПодії, функціяОбробник)
З arrow function (зручніше):
button.addEventListener("click", () => {
console.log("Клік!");
});
Пам'ятаєш callbacks з Block 4? Другий аргумент addEventListener — це саме callback-функція. Браузер викличе її, коли подія відбудеться.
Кілька обробників на одну подію
На один елемент можна повісити скільки завгодно обробників:
const btn = document.querySelector(".btn");
btn.addEventListener("click", () => {
console.log("Обробник 1");
});
btn.addEventListener("click", () => {
console.log("Обробник 2");
});
// При кліку виведе обидва повідомлення
Основні типи подій миші
| Подія | Коли спрацьовує |
|---|---|
click | Клік лівою кнопкою миші |
dblclick | Подвійний клік |
mouseenter | Курсор заходить на елемент |
mouseleave | Курсор покидає елемент |
mouseover | Курсор заходить на елемент або його дочірній |
mouseout | Курсор покидає елемент або його дочірній |
mousedown | Кнопку миші натиснули (до відпускання) |
mouseup | Кнопку миші відпустили |
const card = document.querySelector(".card");
card.addEventListener("mouseenter", () => {
card.classList.add("card--hover");
console.log("Мишка на картці");
});
card.addEventListener("mouseleave", () => {
card.classList.remove("card--hover");
console.log("Мишка пішла з картки");
});
Яка різниця між mouseenter/mouseleave та mouseover/mouseout? Перша пара не спрацьовує при переході між дочірніми елементами. Зазвичай mouseenter/mouseleave зручніші, бо не створюють зайвих спрацювань.
Об'єкт event
Коли подія відбувається, браузер створює об'єкт події з детальною інформацією. Він автоматично передається першим аргументом в обробник:
const button = document.querySelector(".btn");
button.addEventListener("click", (event) => {
console.log(event.type); // "click"
console.log(event.target); // елемент, на якому клікнули
console.log(event.clientX); // X-координата кліку
console.log(event.clientY); // Y-координата кліку
});
Найважливіші властивості event
| Властивість | Опис |
|---|---|
event.type | Тип події ("click", "mouseenter" тощо) |
event.target | Елемент, на якому реально сталася подія |
event.currentTarget | Елемент, на якому висить обробник |
event.clientX / clientY | Координати миші відносно вікна |
event.pageX / pageY | Координати миші відносно сторінки |
document.addEventListener("click", (event) => {
console.log("Клік на:", event.target.tagName);
console.log("Координати:", event.clientX, event.clientY);
});
event.target — де саме клікнули
Це одна з найкорисніших властивостей. event.target вказує на конкретний елемент, на якому сталася подія:
const nav = document.querySelector("nav");
nav.addEventListener("click", (event) => {
// Перевіряємо, чи клікнули саме на посилання
if (event.target.tagName === "A") {
console.log("Натиснули посилання:", event.target.textContent);
}
});
removeEventListener — видалення обробника
Щоб видалити обробник, потрібно передати ту саму функцію:
// Зберігаємо функцію в змінну
const handleClick = () => {
console.log("Клік!");
};
const btn = document.querySelector(".btn");
btn.addEventListener("click", handleClick);
// Пізніше — видаляємо
btn.removeEventListener("click", handleClick);
Анонімну функцію неможливо видалити! Ось цей код не працює:
btn.addEventListener("click", () => console.log("Клік"));
btn.removeEventListener("click", () => console.log("Клік")); // не видалить!Це дві різні функції, хоча виглядають однаково. Щоб мати змогу видалити обробник, завжди зберігай функцію в змінну.
Практика: лічильник кліків
<div class="counter">
<button class="counter__btn counter__btn--minus">-</button>
<span class="counter__value">0</span>
<button class="counter__btn counter__btn--plus">+</button>
</div>
const minusBtn = document.querySelector(".counter__btn--minus");
const plusBtn = document.querySelector(".counter__btn--plus");
const valueDisplay = document.querySelector(".counter__value");
let count = 0;
plusBtn.addEventListener("click", () => {
count++;
valueDisplay.textContent = count;
});
minusBtn.addEventListener("click", () => {
count--;
valueDisplay.textContent = count;
});
Практика: підсвічування елементів
const items = document.querySelectorAll(".gallery-item");
items.forEach((item) => {
item.addEventListener("mouseenter", (event) => {
event.target.classList.add("gallery-item--active");
});
item.addEventListener("mouseleave", (event) => {
event.target.classList.remove("gallery-item--active");
});
});
Старий спосіб: onclick (не рекомендується)
Існує старіший спосіб — через атрибут або властивість:
// Через властивість — дозволяє тільки один обробник
const btn = document.querySelector(".btn");
btn.onclick = () => console.log("Клік");
// Другий присвоєний обробник замінить перший!
btn.onclick = () => console.log("Інший клік"); // попередній загублено
<!-- Через HTML-атрибут — найгірший варіант -->
<button onclick="alert('Клік!')">Натисни</button>
Завжди використовуй addEventListener. Він дозволяє додавати кілька обробників, легко видаляти їх, і тримає JavaScript окремо від HTML.
Підсумок
- Подія — сигнал від браузера, що щось сталося (клік, наведення тощо)
addEventListener(type, handler)— додає обробник подіїevent.target— елемент, на якому реально сталася подіяevent.type— тип події (click, mouseenter тощо)removeEventListener— видаляє обробник (потрібна та сама функція)mouseenter/mouseleave— зручніші заmouseover/mouseout- Завжди використовуй addEventListener замість onclick
Що далі?
У наступному уроці заглибимося в події: bubbling, capturing, event delegation та keyboard events.
Корисні посилання:
- javascript.info: Вступ до подій — детальний огляд подій (українською)
- MDN: addEventListener — документація
- MDN: Event reference — повний список усіх подій