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:
- Ustaw wartość pola wyszukiwarki na tekst elementu etykiety
label
- Dodaj do pola wyszukiwarki klasę
hint
- Usuń etykietę
- Powiąż z polem wyszukiwarki zdarzenie
focus
, które usunie tekst podpowiedzi oraz klasęhint
- 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:
- Ukryj wszystkie moduły (elementy
div
z klasąmodule
). - Przed pierwszym modułem utwórz nieuporządkowaną listę.
- Przejdź iteracyjnie przez moduły za pomocą metody
$.fn.each
. Dla każdego modułu użyj tekstu elementuh2
jako tekstu pozycji, którą dodajesz do nieuporządkowanej listy. - 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
- Na koniec pokaż pierwszą kartę.