Rozdział 5. Zdarzenia jQuery

> Dodaj do ulubionych

Wprowadzenie

Posługując się dostępnymi w bibliotece jQuery metodami możemy w łatwy sposób podpiąć procedurę obsługi zdarzeń do wybranych elementów. Kiedy ma miejsce jakieś zdarzenie, zostanie wykonana przypisana mu funkcja. Słowo this wewnątrz funkcji odwołuje się do klikniętego elementu.

Szczegółowe informacje na temat zdarzeń jQuery znajdziesz na stronie http://api.jquery.com/category/events/.

Funkcja obsługi zdarzeń może przyjąć obiekt zdarzenia. Za jego pomocą można określić typ zdarzenia i wyłączyć jego domyślne zachowanie.

Szczegółowe informacje na temat obiektów zdarzeń znajdziesz na stronie http://api.jquery.com/category/events/event-object/.

Przypisywanie zdarzeń do elementów

Dla powszechnie występujących zdarzeń w bibliotece jQuery dostępne są metody pomocnicze — to właśnie z nich korzysta się najczęściej. Metody te, między innymi $.fn.click, $.fn.focus, $.fn.blur, $.fn.change itp., stanowią skrócone wersje metody $.fn.bind. Z metody wiązania warto skorzystać, jeśli chcemy powiązać jedną funkcję obsługi z kilkoma zdarzeniami, przekazać procedurze dane bądź przekazać obiekt zawierający kilka zdarzeń i procedur obsługi. Metoda bind przydatna jest również w pracy z własnymi zdarzeniami.

Przykład 5.1. Wiązanie zdarzeń przy użyciu metody pomocniczej

$('p').click(function() {
	    console.log('klik');
	});

Przykład 5.2. Wiązanie zdarzeń za pomocą metody $.fn.bind

$('p').bind('click', function() {
	    console.log('klik');
	});

Przykład 5.3. Wiązanie zdarzeń za pomocą metody $.fn.bind z danymi

$('input').bind(
	    'click change',  // wiąże dwa zdarzenia
	    { foo : 'bar' }, // przekazuje dane
	 
	    function(obiektZdarzenia) {
	        console.log(obiektZdarzenia.type, obiektZdarzenia.data);
	        // rejestruje typ zdarzenia, a następnie { foo : 'bar' }
	    }
	);

Jednorazowe wykonywanie zarejestrowanych zdarzeń

Czasami chcemy, aby wybrana procedura obsługi zdarzeń została wykonana tylko raz, zaś po niej inna lub żadna. Rozwiązanie tego problemu stanowi dostępna w jQuery metoda $.fn.one.

Przykład 5.4. Przełączanie procedur obsługi zdarzeń za pomocą metody $.fn.one

$('p').one('click', function() {
	    console.log('Pierwsze kliknięcie!');
	    $(this).click(function() { console.log('Już to kliknąłeś!'); });
	});

Metoda $.fn.one przydaje się zwłaszcza wtedy, gdy trzeba wprowadzić jakieś skomplikowane ustawienia tylko po pierwszym kliknięciu elementu.

Usuwanie zdarzeń

Do odłączania procedury obsługi zdarzeń od elementów służy metoda $.fn.unbind, do której przekazuje się typ wybranego zdarzenia. Jeśli do zdarzenia podpięta była funkcja nazwana, można ją odłączyć poprzez przekazanie jej w miejsce drugiego argumentu.

Przykład 5.5. Usuwamy wszystkie procedury obsługi zdarzenia click na wybranym elemencie

$('p').unbind('click');

Przykład 5.6. Usuwamy konkretną procedurę obsługi zdarzenia click

var foo = function() { console.log('foo'); };
	var bar = function() { console.log('bar'); };
	 
	$('p').bind('click', foo).bind('click', bar);
	$('p').unbind('click', bar); // foo jest wciąż powiązane ze zdarzeniem click

Tworzenie przestrzeni nazw zdarzeń

Jeśli dzielisz z innymi złożone aplikacje lub wtyczki, warto dla swoich zdarzeń utworzyć przestrzeń nazw — dzięki temu nie odepniesz przypadkiem zdarzeń, o których nie wiedziałeś bądź nie mogłeś wiedzieć.

Przykład 5.7: Tworzenie przestrzeni nazw zdarzeń

$('p').bind('click.mojaPrzestrzenNazw', function() { /* ... */ });
	$('p').unbind('click.mojaPrzestrzenNazw');
	$('p').unbind('.mojaPrzestrzenNazw'); // odpina wszystkie zdarzenia w danej przestrzeni nazw

Wiązanie kilku zdarzeń

Dość często elementy aplikacji powiązane są z kilkoma zdarzeniami, a każde z nich ma swoją własną funkcję obsługi. W takich przypadkach możesz do funkcji $.fn.bind przekazać jakiś obiekt wraz z jedną lub kilkoma parami klucz-wartość — kluczem jest wówczas nazwa zdarzenia, a wartością funkcja obsługująca dane zdarzenie.

Przykład 5.8. Wiązanie kilku zdarzeń

$('p').bind({
	    'click': function() { console.log('kliknąłeś!'); },
	    'mouseover': function() { console.log('najechałeś kursorem!'); }
	});

Funkcja obsługi zdarzeń

Jak dowiedziałeś się we wprowadzeniu, funkcja obsługi zdarzeń przyjmuje obiekt zdarzenia, który zawiera wiele własności i metod. Obiekt zdarzenia najczęściej wyłącza domyślną akcję zdarzenia, do czego wykorzystuje się metodę preventDefault. Inne dostępne w obiekcie zdarzenia własności i metody to między innymi:

pageX, pageY
Pozycja kursora względem lewego górnego rogu strony w momencie wystąpienia zdarzenia.
type
Typ zdarzenia (np. click).
which
Przycisk bądź klawisz, który został naciśnięty.
data
Dane, które zostały przekazane w czasie, gdy zdarzenie było podpięte.
target
Element DOM, który zainicjował zdarzenie.
preventDefault()
Blokuje domyślną akcję zdarzenia (np. otworzenie odnośnika).
stopPropagation()
Zapobiega rozprzestrzenianiu się zdarzenia na kolejne elementy.

Dodatkowo funkcja obsługi zdarzeń ma także dostęp poprzez słowo kluczowe this do elementu DOM, do którego została przypisana. Aby przekształcić element DOM w obiekt jQuery, na którym mogą być wywoływane metody biblioteki, wystarczy skorzystać z konstrukcji $(this). Często w tym celu korzysta się z poniższej składni:

1	var $this = $(this);

Wyzwalanie procedur obsługi zdarzeń

Dostępna w bibliotece jQuery metoda $.fn.trigger pozwala wyzwolić procedury obsługi zdarzeń związane z elementem bez jakiegokolwiek udziału użytkownika. Metoda ta ma kilka zastosowań, jednak nie powinno się jej wykorzystywać tylko do wywołania funkcji, która została podpięta do obsługi zdarzenia click. Powinieneś zamiast tego zapisać funkcję, którą chcesz wywołać w zmiennej i przekazać nazwę tej zmiennej w czasie wiązania procedury obsługi zdarzeń z elementami. Później będziesz mógł wywołać samą funkcję kiedy tylko zechcesz, bez użycia metody $.fn.trigger.

Właściwy sposób wyzwalania procedury obsługi zdarzeń

var foo = function(z) {
	    if (z) {
	        console.log(z);
	    } else {
	        console.log('to nie jest wynik zdarzenia!');
	    }
	};
	 
	 
	$('p').click(foo);
	 
	foo(); // zamiast $('p').trigger('click')

Zwiększanie wydajności kodu za pomocą delegacji zdarzeń

Bibliotekę jQuery bardzo często wykorzystuje się do dodawania nowych elementów na stronę. Czasem możesz chcieć powiązać z nimi zdarzenia — te same, które powiązałeś już z podobnymi elementami znajdującymi się na stronie. Zamiast wiązać zdarzenia z każdym dodawanym elementem, możesz skorzystać z delegacji zdarzeń — wiążesz wtedy zdarzenie z elementem kontenera, a po wystąpieniu zdarzenia sprawdzasz, dla którego elementu znajdującego się w kontenerze wystąpiło. Definicja ta może wydawać się skomplikowana, lecz na szczęście w bibliotece jQuery dostępne są proste metody $.fn.live i $.fn.delegate.

Podczas gdy większość programistów korzysta z delegacji zdarzeń, gdy muszą dodać elementy do strony po jej wczytaniu w przeglądarce, technika ta jest korzystna także z innego powodu. Powiązanie procedur obsługi zdarzeń z setkami elementów zabiera mnóstwo czasu — jeśli zatem masz duży zbiór elementów, być może powinieneś powiązać odpowiednie zdarzenia z elementem kontenera korzystając z delegacji zdarzeń.

Delegacja zdarzeń za pomocą metody $.fn.delegate

$('#mojaNieuporzadkowanaLista').delegate('li', 'click', function(z) {
	    var $mojaPozycjaNaLiscie = $(this);
	    // ...
	});

Delegacja zdarzeń za pomocą metody $.fn.live

$('#mojaNieuporzadkowanaLista li').live('click', function(z) {
	    var $mojaPozycjaNaLiscie = $(this);
	    // ...
	});

Usuwanie zdarzeń delegowanych

Jeśli musisz usunąć delegowane zdarzenia, nie możesz tego zrobić za pomocą metody unbind. Zamiast tego skorzystaj z metody $.fn.undelegate dla zdarzeń powiązanych z metodą $.fn.delegate, a z $.fn.die dla zdarzeń związanych z $.fn.live. Tak jak w przypadku metody bind, możesz opcjonalnie przekazać nazwę podpiętej funkcji.

Usuwanie zdarzeń delegowanych

$('#mojaNieuporzadkowanaLista').undelegate('li', 'click');
	$('#mojaNieuporzadkowanaLista li').die('click');

Funkcje pomocnicze zdarzeń

W bibliotece jQuery dostępne są dwie związane ze zdarzeniami funkcje pomocnicze, które oszczędzą ci nieco pracy.

$.fn.hover

Do metody $.fn.hover można przekazać jedną lub dwie funkcje, które mają zostać wykonane, kiedy dla danego elementu zajdzie zdarzenie mouseenter lub mouseleave. Jeśli przekażesz jedną funkcję, będzie ona wykonywana dla obydwu zdarzeń, zaś jeśli przekażesz dwie to pierwsza z nich będzie wykonywana dla zdarzenia mouseenter, a druga dla mouseleave.

Funkcja pomocnicza hover

$('#menu li').hover(function() {
	    $(this).toggleClass('hover');
	});
$.fn.toggle

Metoda $.fn.toggle wyzwalana jest przez zdarzenie click i przyjmuje co najmniej dwie funkcje. Za każdym razem, kiedy zachodzi zdarzenie click, wywoływana jest kolejna funkcja z listy. Z reguły metoda $.fn.toggle używana jest tylko z dwiema funkcjami, choć liczba funkcji, jaką może przyjąć jest nieograniczona. Miej jednak na uwadze, że przekazanie długiej listy funkcji utrudnia znajdowanie ewentualnych błędów.

Funkcja pomocnicza toggle

$('p.expander').toggle(
	    function() {
	        $(this).prev().addClass('open');
	    },
	    function() {
	        $(this).prev().removeClass('open');
	    }
	);

Ćwiczenia

Podpowiedź w polu wyszukiwarki

Otwórz w przeglądarce plik /exercises/index.html, a także skorzystaj z pliku /exercises/js/inputHint.js bądź z Firebuga. Twoim zadaniem jest użyć tekstu etykiety pola wyszukiwarki do utworzenia podpowiedzi dla wpisywanego w pole wejściowe zapytania. W tym celu:

  1. Ustaw wartość pola wyszukiwarki na tekst elementu etykiety label
  2. Dodaj do pola wyszukiwarki klasę hint
  3. Usuń etykietę
  4. Powiąż z polem wyszukiwarki zdarzenie focus, które usunie tekst podpowiedzi oraz klasę hint
  5. Powiąż z polem wyszukiwarki zdarzenie blur, które przywraca tekst podpowiedzi i klasę hint, jeśli do wyszukiwarki nie został wpisany żaden tekst

Co jeszcze wziąłbyś pod uwagę, gdybyś miał opracować taką funkcję dla prawdziwej wyszukiwarki?

System nawigacji strony oparty na kartach

Otwórz w przeglądarce plik /exercises/index.html, a także skorzystaj z pliku /exercises/js/tabs.js. Twoim zadaniem jest opracowanie nawigacji opartej na kartach dla dwóch elementów div.module. W tym celu:

  1. Ukryj wszystkie moduły (elementy div z klasą module).
  2. Przed pierwszym modułem utwórz nieuporządkowaną listę.
  3. Przejdź iteracyjnie przez moduły za pomocą metody $.fn.each. Dla każdego modułu użyj tekstu elementu h2 jako tekstu pozycji, którą dodajesz do nieuporządkowanej listy.
  4. Powiąż z pozycją na liście zdarzenie click, które:
    • Pokazuje odpowiedni moduł, a resztę ukrywa
    • Dodaje klasę current do klikniętej pozycji na liście
    • Usuwa klasę current z poprzednio klikniętego elementu
  5. Na koniec pokaż pierwszą kartę.

Autor: Rebecca Murphey

Źródło: http://github.com/rmurphey/jqfundamentals

Tłumaczenie: Joanna Liana

Treść tej strony jest dostępna na zasadach licencji CC BY-SA 3.0 US