16: Evenimente
Răspunde la acțiunile utilizatorului cu addEventListener — click, submit, input, keydown.
Lecția 16 · Evenimente¶
Ce vei învăța
- Ce sunt evenimentele și trei moduri de a le asculta
- De ce
addEventListenere alegerea modernă - Evenimentele comune:
click,submit,input,change,keydown - Obiectul
event:e.target,e.preventDefault,e.stopPropagation - Event bubbling și delegation (pe scurt)
Ce sunt evenimentele?¶
Un eveniment e o „întâmplare” în browser: un click, o tastă apăsată, un formular trimis, o pagină încărcată. JavaScript poate asculta aceste evenimente și rula cod ca răspuns.
Exemple de evenimente pe care le vei folosi des:
click— utilizatorul apasă un buton sau un link.submit— un<form>e trimis.input— textul dintr-un<input>s-a schimbat.change— s-a schimbat valoarea unui<select>sau unui checkbox.keydown— s-a apăsat o tastă.DOMContentLoaded— HTML-ul e parsat și DOM-ul e gata.
Trei moduri (din vechi în nou)¶
1. Inline în HTML (EVITĂ)¶
Amestecă logică cu structură. Nu folosi.
2. Proprietate on<eveniment>¶
Limitat la un singur handler — dacă îl setezi de două ori, al doilea îl suprascrie.
3. addEventListener (RECOMANDAT)¶
const btn = document.querySelector("button");
btn.addEventListener("click", () => {
alert("salut");
});
Avantaje:
- Poți adăuga multiple handlere pentru același eveniment.
- Poți specifica opțiuni (
once,passive,capture). - Ușor de scos cu
removeEventListener.
addEventListener¶
Semnătura:
tipEveniment— un string:"click","submit","keydown", etc. (fără „on”).handler— funcția care se rulează la eveniment.optiuni— opțional, obiect:{ once: true },{ passive: true },{ capture: true }.
Exemple:
const btn = document.querySelector("#salut-btn");
btn.addEventListener("click", () => {
console.log("Ai dat click!");
});
// Handler care rulează o singură dată
btn.addEventListener("click", () => alert("doar o dată"), { once: true });
Evenimente comune¶
click și dblclick¶
btn.addEventListener("click", () => console.log("click simplu"));
btn.addEventListener("dblclick", () => console.log("dublu click"));
input — la fiecare tastă¶
const cautare = document.querySelector("#cautare");
cautare.addEventListener("input", (e) => {
console.log("Utilizatorul a scris:", e.target.value);
});
change — când se schimbă un select / checkbox¶
const optiune = document.querySelector("#optiune");
optiune.addEventListener("change", (e) => {
console.log("Nouă valoare:", e.target.value);
});
submit — la trimiterea unui form¶
const form = document.querySelector("#formular");
form.addEventListener("submit", (e) => {
e.preventDefault(); // oprește reîncărcarea paginii
console.log("Form trimis!");
});
keydown, keyup, keypress¶
e.key e string-ul tastei: "a", "Enter", "ArrowUp", " " (spațiu), etc.
mouseenter / mouseleave¶
const card = document.querySelector(".card");
card.addEventListener("mouseenter", () => card.classList.add("hover"));
card.addEventListener("mouseleave", () => card.classList.remove("hover"));
load / DOMContentLoaded¶
// HTML-ul e parsat (fără a aștepta imagini mari)
document.addEventListener("DOMContentLoaded", () => {
console.log("DOM gata!");
});
// Totul e încărcat: HTML + CSS + imagini + scripturi
window.addEventListener("load", () => {
console.log("Totul e gata!");
});
Dacă folosești <script defer>, scriptul rulează automat după ce DOM-ul e parsat — deci de obicei nu mai ai nevoie de DOMContentLoaded.
Obiectul event¶
Handler-ul primește automat un obiect event (de obicei numit e sau event):
btn.addEventListener("click", (e) => {
console.log(e.type); // "click"
console.log(e.target); // elementul pe care s-a declanșat
console.log(e.clientX, e.clientY); // coordonatele mouse-ului
});
Cele mai utile proprietăți / metode:
| Proprietate / metodă | Ce face |
|---|---|
e.target |
elementul pe care s-a declanșat evenimentul |
e.currentTarget |
elementul pe care ai atașat listener-ul |
e.type |
tipul evenimentului ("click", etc.) |
e.preventDefault() |
oprește comportamentul default |
e.stopPropagation() |
oprește propagarea spre părinți |
e.key |
tasta apăsată (pentru keydown) |
preventDefault()¶
Unele elemente au comportament default:
- Un
<a href>navighează când e click. - Un
<form>reîncarcă pagina când esubmit. Spacepe pagină o scrollează.
Ca să-l oprești:
const link = document.querySelector("a");
link.addEventListener("click", (e) => {
e.preventDefault();
console.log("Am oprit navigarea.");
});
const form = document.querySelector("form");
form.addEventListener("submit", (e) => {
e.preventDefault(); // procesează în JS, nu reîncărca
// ... validează, trimite cu fetch, etc.
});
Event bubbling¶
Când apeși pe un element, evenimentul urcă (bubble) prin părinți până la document:
document.getElementById("exterior").addEventListener("click", () => {
console.log("div exterior");
});
document.getElementById("buton").addEventListener("click", () => {
console.log("buton");
});
Click pe buton afișează:
Evenimentul „a urcat” de la buton la div.
stopPropagation¶
Dacă nu vrei propagarea:
document.getElementById("buton").addEventListener("click", (e) => {
e.stopPropagation();
console.log("Doar buton.");
});
Event delegation (pe scurt)¶
Bubbling-ul permite o șmecherie elegantă: atașezi listener pe un părinte și folosești e.target ca să știi pe ce s-a dat click. Util pentru copii dinamici (creați după ce ai pornit):
document.querySelector("#lista").addEventListener("click", (e) => {
if (e.target.tagName === "LI") {
e.target.classList.toggle("selectat");
}
});
Nu mai trebuie să pui listener pe fiecare <li> nou creat.
Scoaterea unui listener — removeEventListener¶
Ca să poți scoate un listener, trebuie să ai referința la funcție (deci nu anonimă):
function handler() {
console.log("odată");
}
btn.addEventListener("click", handler);
btn.removeEventListener("click", handler);
Dacă ai nevoie doar să ruleze o dată, folosește opțiunea once:
Exerciții¶
Exercițiu 1 — Alert la click¶
Un buton care la click afișează un alert cu „Salut!”.
Soluție
Exercițiu 2 — Log la tastare¶
Un <input> care loghează valoarea curentă la fiecare tastă.
Soluție
Exercițiu 3 — Schimbă culoarea fundalului¶
Un buton care la fiecare click schimbă culoarea fundalului paginii (random).
Soluție
const btn = document.getElementById("schimba");
const culoareRandom = () => {
const r = Math.floor(Math.random() * 256);
const g = Math.floor(Math.random() * 256);
const b = Math.floor(Math.random() * 256);
return `rgb(${r}, ${g}, ${b})`;
};
btn.addEventListener("click", () => {
document.body.style.backgroundColor = culoareRandom();
});
Exercițiu 4 — Afișează tasta apăsată¶
Pagina afișează pe ecran ce tastă a fost apăsată ultima.
Soluție
Mini-proiect: Click counter¶
Un buton care numără câte click-uri a primit și afișează rezultatul. Plus un buton „Reset” care pune contorul la zero.
Cod complet:
<!DOCTYPE html>
<html lang="ro">
<head>
<meta charset="UTF-8" />
<title>Click counter</title>
<script src="app.js" defer></script>
<style>
body {
font-family: sans-serif;
padding: 2rem;
text-align: center;
}
#scor {
font-size: 3rem;
font-weight: bold;
color: #2563eb;
}
button {
font-size: 1rem;
padding: 0.75rem 1.5rem;
margin: 0.5rem;
cursor: pointer;
}
</style>
</head>
<body>
<h1>Click counter</h1>
<p>Scor: <span id="scor">0</span></p>
<button id="btn-click">Apasă-mă!</button>
<button id="btn-reset">Reset</button>
</body>
</html>
// Selectăm elementele
const scor = document.getElementById("scor");
const btnClick = document.getElementById("btn-click");
const btnReset = document.getElementById("btn-reset");
let counter = 0;
// Incrementează la click
btnClick.addEventListener("click", () => {
counter++;
scor.textContent = counter;
});
// Resetează
btnReset.addEventListener("click", () => {
counter = 0;
scor.textContent = counter;
});
Idei de extindere:
- Salvează scorul în
localStorageca să rămână după reîncărcare. - Schimbă culoarea scorului după prag (100 = auriu, 500 = curcubeu).
- Adaugă un al doilea buton cu valoare negativă („scade”).
Rezumat¶
- Evenimentele sunt acțiunile utilizatorului (click, tastare, submit) la care JS poate reacționa.
- Folosește
addEventListener(tip, handler)— permite multiple handlere și opțiuni. - Handler-ul primește un obiect
eventcutarget,type,key, etc. e.preventDefault()oprește comportamentul default (navigare, reload de form).- Event bubbling: evenimentul urcă prin părinți. Delegation: ascultă pe părinte pentru copii dinamici.
- Pentru a rula o dată, folosește
{ once: true }în opțiuni.
Pasul următor: → Lecția 17: Formulare cu validare JS