Lekcja 7: Zdarzenia w jQuery - Podstawowe Wiązanie (.on()
, .off()
)
Interaktywność stron internetowych opiera się w dużej mierze na reagowaniu na działania użytkownika, takie jak kliknięcia myszą, najechanie kursorem, wpisywanie tekstu czy wysyłanie formularzy. jQuery dostarcza potężny i elastyczny system obsługi zdarzeń, który ułatwia podłączanie funkcji (tzw. event handlerów) do elementów DOM, aby wykonywały określone akcje w odpowiedzi na te zdarzenia.
Podstawowa Metoda: .on()
Metoda .on()
jest podstawowym i najbardziej wszechstronnym sposobem dołączania obsługi zdarzeń w jQuery (od wersji 1.7 zastąpiła starsze metody jak .bind()
, .live()
, .delegate()
).
$(selektor).on(nazwaZdarzenia, [dane], funkcjaObslugujaca);
selektor
: Element(y), do których chcemy dołączyć obsługę zdarzenia.nazwaZdarzenia
: String określający typ zdarzenia (np.'click'
,'mouseenter'
,'keydown'
). Można podać wiele zdarzeń rozdzielonych spacją (np.'mouseenter mouseleave'
).[dane]
(opcjonalne): Obiekt zawierający dodatkowe dane, które chcemy przekazać do funkcji obsługującej zdarzenie. Dostępne wewnątrz funkcji jakoevent.data
.funkcjaObslugujaca
: Funkcja, która zostanie wykonana, gdy zdarzenie wystąpi na wybranym elemencie. Otrzymuje ona jako argument obiekt zdarzenia (event
).
Przykłady Użycia .on()
// Proste kliknięcie przycisku
$("#mojPrzycisk").on("click", function(event) {
console.log("Przycisk został kliknięty!");
// event - obiekt zdarzenia, zawiera informacje o zdarzeniu
console.log("Typ zdarzenia:", event.type); // "click"
console.log("Element docelowy:", event.target); // Element HTML, który został kliknięty
});
// Reakcja na najechanie i zjechanie myszką
$(".zdjecie").on("mouseenter", function() {
$(this).addClass("podswietlone"); // 'this' wewnątrz funkcji odnosi się do elementu, na którym wystąpiło zdarzenie
});
$(".zdjecie").on("mouseleave", function() {
$(this).removeClass("podswietlone");
});
// Obsługa wielu zdarzeń jedną funkcją
$("input[type='text']").on("focus blur", function(event) {
if (event.type === "focus") {
$(this).addClass("aktywne-pole");
console.log("Pole otrzymało fokus.");
} else { // event.type === "blur"
$(this).removeClass("aktywne-pole");
console.log("Pole straciło fokus.");
}
});
// Przekazywanie danych do handlera
$("button.produkt").on("click", { znizka: 0.1, waluta: "PLN" }, function(event) {
let cena = parseFloat($(this).attr("data-cena"));
let cenaPoZnizce = cena * (1 - event.data.znizka);
console.log("Cena po zniżce:", cenaPoZnizce.toFixed(2), event.data.waluta);
});
Obiekt Zdarzenia (event
)
Funkcja obsługująca zdarzenie otrzymuje obiekt event
, który zawiera wiele użytecznych informacji i metod:
event.type
: Typ zdarzenia (np. "click").event.target
: Element DOM, na którym pierwotnie wystąpiło zdarzenie (najgłębszy element).event.currentTarget
(lubthis
w funkcji): Element DOM, do którego aktualnie jest dołączony handler (ten, na którym wywołano.on()
).event.preventDefault()
: Metoda zapobiegająca domyślnej akcji przeglądarki dla danego zdarzenia (np. przejście do linku po kliknięciu<a>
, wysłanie formularza po kliknięciu przycisku submit).event.stopPropagation()
: Metoda zatrzymująca propagację (bąbelkowanie) zdarzenia w górę drzewa DOM. Zdarzenie nie dotrze do elementów nadrzędnych.event.pageX
/event.pageY
: Współrzędne kursora myszy względem lewego górnego rogu dokumentu (dla zdarzeń myszy).event.which
: Kod klawisza (dla zdarzeń klawiatury, np.keydown
).event.data
: Obiekt z danymi przekazanymi jako opcjonalny argument do.on()
.
$("a.specjalny-link").on("click", function(event) {
event.preventDefault(); // Zapobiegaj przejściu do adresu URL
console.log("Kliknięto specjalny link, ale nie przechodzimy dalej.");
});
$("#rodzic").on("click", function() {
console.log("Kliknięto rodzica.");
});
$("#dziecko").on("click", function(event) {
console.log("Kliknięto dziecko.");
event.stopPropagation(); // Zapobiegaj bąbelkowaniu do rodzica
});
Usuwanie Obsługi Zdarzeń: .off()
Metoda .off()
służy do usuwania handlerów zdarzeń dołączonych wcześniej za pomocą .on()
.
$(selektor).off(nazwaZdarzenia, [funkcjaObslugujaca]);
- Bez argumentów:
$(selektor).off()
usuwa wszystkie handlery zdarzeń dołączone przez jQuery do wybranych elementów. - Z nazwą zdarzenia:
$(selektor).off("click")
usuwa wszystkie handlery dla zdarzenia "click". - Z nazwą zdarzenia i funkcją:
$(selektor).off("click", mojaFunkcja)
usuwa tylko konkretny handler (mojaFunkcja
) dla zdarzenia "click". Ważne: Aby to zadziałało, funkcja musi być nazwaną funkcją lub zmienną przechowującą funkcję, a nie funkcją anonimową zdefiniowaną bezpośrednio w.on()
.function obslugaKlikniecia() { console.log("Kliknięto!"); } // Dołączenie nazwanej funkcji $("#przycisk").on("click", obslugaKlikniecia); // ... później ... // Usunięcie konkretnego handlera $("#przycisk").off("click", obslugaKlikniecia);
Skrócone Metody Zdarzeń
jQuery dostarcza również skróconych metod dla najpopularniejszych zdarzeń, np. .click()
, .mouseenter()
, .keydown()
, .submit()
itp. Są one równoważne wywołaniu .on()
z odpowiednią nazwą zdarzenia.
// Równoważne: $("#przycisk").on("click", funkcja);
$("#przycisk").click(function() {
console.log("Kliknięto przycisk (metoda skrócona).");
});
// Równoważne: $("input").on("focus", funkcja);
$("input").focus(function() {
$(this).css("border-color", "blue");
});
// Wywołanie zdarzenia bez podania funkcji (trigger)
$("#przycisk").click(); // Symuluje kliknięcie przycisku
Chociaż metody skrócone są wygodne, zaleca się używanie .on()
ze względu na jego wszechstronność, zwłaszcza przy pracy z delegowaniem zdarzeń (omówionym w następnej lekcji).
Zadanie praktyczne
Stwórz plik HTML z:
- Przyciskiem z ID "kliknij-mnie".
- Paragrafem z ID "licznik" i początkową treścią "Kliknięcia: 0".
- Div-em z ID "hover-box" o wymiarach 100x100px i szarym tle.
- Linkiem
<a href="https://google.com" id="link-test">Link do Google</a>
.
Używając jQuery i metody .on()
:
- Dodaj handler do przycisku "kliknij-mnie", który po każdym kliknięciu zwiększy liczbę w paragrafie "licznik".
- Dodaj handler do diva "hover-box", który po najechaniu myszką zmieni jego tło na zielone, a po zjechaniu myszką przywróci szare tło.
- Dodaj handler do linku "link-test", który po kliknięciu wyświetli komunikat w konsoli "Kliknięto link!" i zapobiegnie przejściu do Google (użyj
event.preventDefault()
).
Pokaż rozwiązanie
HTML:
<!DOCTYPE html>
<html>
<head>
<title>Test Zdarzeń jQuery</title>
<style>
#hover-box {
width: 100px;
height: 100px;
background-color: lightgray;
margin-top: 10px;
}
</style>
</head>
<body>
<button id="kliknij-mnie">Kliknij Mnie</button>
<p id="licznik">Kliknięcia: 0</p>
<div id="hover-box"></div>
<a href="https://google.com" id="link-test">Link do Google</a>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script>
$(function() {
let liczbaKlikniec = 0;
// 1. Obsługa kliknięcia przycisku
$("#kliknij-mnie").on("click", function() {
liczbaKlikniec++;
$("#licznik").text("Kliknięcia: " + liczbaKlikniec);
console.log("Kliknięto przycisk.");
});
// 2. Obsługa najechania i zjechania myszką (dwa handlery)
/*
$("#hover-box").on("mouseenter", function() {
$(this).css("background-color", "lightgreen");
console.log("Najechano na box.");
});
$("#hover-box").on("mouseleave", function() {
$(this).css("background-color", "lightgray");
console.log("Zjechano z boxa.");
});
*/
// 2. Alternatywa: Obsługa najechania i zjechania (jeden handler dla wielu zdarzeń)
$("#hover-box").on("mouseenter mouseleave", function(event) {
if (event.type === "mouseenter") {
$(this).css("background-color", "lightgreen");
console.log("Najechano na box.");
} else { // mouseleave
$(this).css("background-color", "lightgray");
console.log("Zjechano z boxa.");
}
});
// 3. Obsługa kliknięcia linku
$("#link-test").on("click", function(event) {
event.preventDefault(); // Zapobiegaj domyślnej akcji
console.log("Kliknięto link! Przejście zablokowane.");
});
});
</script>
</body>
</html>
Zadanie do samodzielnego wykonania
Dodaj do HTML pole input tekstowe (<input type="text" id="tekst-input">
) oraz paragraf (<p id="wpisany-tekst"></p>
).
Używając jQuery:
- Dodaj handler do pola input, który będzie reagował na zdarzenie
keyup
(zwolnienie klawisza). - Wewnątrz handlera
keyup
, pobierz aktualną wartość z pola input (.val()
) i wstaw ją jako treść paragrafu "wpisany-tekst" (.text()
). W ten sposób paragraf będzie na bieżąco pokazywał, co jest wpisywane w polu input. - Dodaj drugi przycisk "Wyłącz Licznik". Po jego kliknięciu, użyj
.off("click")
, aby usunąć handler zwiększający licznik z przycisku "kliknij-mnie" (z zadania praktycznego).
FAQ - Podstawowe Zdarzenia w jQuery
Jakie są najczęstsze typy zdarzeń?
Najpopularniejsze to: click
, dblclick
(podwójne kliknięcie), mouseenter
(najazd myszą), mouseleave
(zjazd myszą), mouseover
/mouseout
(podobne, ale inaczej obsługują bąbelkowanie), mousemove
(ruch myszą), keydown
(wciśnięcie klawisza), keyup
(zwolnienie klawisza), keypress
(wciśnięcie klawisza generującego znak), focus
(otrzymanie fokusu przez element), blur
(utrata fokusu), change
(zmiana wartości w polu formularza), submit
(wysłanie formularza), scroll
(przewijanie), resize
(zmiana rozmiaru okna).
Co oznacza $(function() { ... });
?
Jest to skrócony zapis dla $(document).ready(function() { ... });
. Kod wewnątrz tej funkcji zostanie wykonany dopiero wtedy, gdy całe drzewo DOM zostanie w pełni załadowane i przetworzone przez przeglądarkę. Jest to standardowa praktyka, aby upewnić się, że elementy, do których chcemy się odwołać, już istnieją.
Czym różni się event.target
od this
(lub event.currentTarget
)?
event.target
to element, który bezpośrednio wywołał zdarzenie (np. kliknięty <span>
wewnątrz przycisku). this
(lub event.currentTarget
) to element, do którego dołączyliśmy handler zdarzenia (np. sam przycisk <button>
). Różnica jest istotna przy delegowaniu zdarzeń.
Czy mogę dołączyć wiele handlerów do tego samego zdarzenia na jednym elemencie?
Tak. Jeśli wywołasz .on("click", funkcja1)
a potem .on("click", funkcja2)
na tym samym elemencie, obie funkcje (funkcja1
i funkcja2
) zostaną wykonane po kliknięciu, w kolejności ich dołączenia.
Jak usunąć tylko jeden konkretny handler, jeśli użyłem funkcji anonimowej w .on()
?
Bezpośrednio nie jest to możliwe za pomocą .off(typ, funkcja)
, ponieważ nie masz referencji do tej anonimowej funkcji. W takich przypadkach można użyć przestrzeni nazw zdarzeń (np. .on("click.mojaPrzestrzen", ...)
i potem .off("click.mojaPrzestrzen")
) lub usunąć wszystkie handlery danego typu (.off("click")
), co często jest wystarczające.