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);

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:

$("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]);

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:

Używając jQuery i metody .on():

  1. Dodaj handler do przycisku "kliknij-mnie", który po każdym kliknięciu zwiększy liczbę w paragrafie "licznik".
  2. 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.
  3. 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:

  1. Dodaj handler do pola input, który będzie reagował na zdarzenie keyup (zwolnienie klawisza).
  2. 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.
  3. 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.