JQuery - Zdarzenia Udostępnij na: Facebook

Autor: Artur Jankowski

Opublikowano: 2011-11-07

Ci z Was, którzy mieli już do czynienia z językiemJavaScript, zapewne pamiętają takie zdarzenia, inicjowane przez użytkownika, jak chociażby onclick. W jQuery wygląda to bardzo podobnie, z tym że usunięty jest prefix „on”. Na wstępie warto wiedzieć, że zapewniają nam doskonałą interaktywność, pomiędzy użytkownikiem a stroną WWW. Zatem zaczynajmy.

Obsługa zdarzeń – funkcja bind

Aby pewien ciąg instrukcji wykonał się po pewnej czynności, należy zastosować funkcję bind.

Załóżmy, że chcemy po kliknięciu w pewien paragraf o identyfikatorze „change-color” zmienić kolor czcionki całego dokumentu na inny, zdefiniowany w klasie „new-color”. Z poprzeniego artykułu dowiedzieliśmy się już, jak dodać klasę. Aby tego dokonać, należy użyć funkcji addClass([nazwa klasy]).

Jak zatem powiązać kliknięcie paragrafu ze zmianą klasy? Po zapoznaniu się z kodem, umieszczonym poniżej, nie powinno być już żadnych pytań.

$(document).ready(function(){
$(‘#change-color’).bind(‘click’,function(){$(‘body’).addClass(‘new-color’)})
});

Jak widać funkcja bind() pozwala powiązać dowolne zdarzenie na wybranym przez nas elemencie z dowolnym działaniem (funkcją).

Obsługa zdarzeń – funkcje zdarzeniowe

Niektóre ze zdarzeń, takie jak np. „click” czy „mouseover”, są bardzo często wykorzystywane. Twórcy jQuery doskonale o tym wiedzą i właśnie dlatego powstały metody skrótowe zdarzeń. Działanie ich jest równoznaczne z działaniem funkcji bind, jednak kod, który musimy stworzyć, aby osiągnąć ten sam efekt, jest po prostu krótszy.

Zamiast:

$(‘#change-color’).bind(‘click’,function(){$(‘body’).addClass(‘new-color’)});

możemy napisać:

$(‘#change-color’).click(function(){$(‘body’).addClass(‘new-color’)});

W tym przypadku metodą do zarejestrowania pewnego zachowania jest metoda “click”.

metoda zdarzeniowa opis
click metoda jest wywoływana po kliknięciu na element
dbclick metoda jest wywoływana po dwukrotnym kliknięciu na element
keydown metoda jest wywoływana po wciśnięciu klawisza, podczas gdy element jest aktywny
keypress metoda jest wywoływana po wprowadzeniu znaku, podczas gdy element jest aktywny
keyup metoda jest wywoływana po zwolnieniu klawisza, podczas gdy element jest aktywny
focus metoda jest wywoływana, gdy element staje się aktywny dla klawiatury
change metoda jest wywoływana wówczas, gdy wartość elementu ulegnie zmianie
mouseenter metoda jest wywoływana wówczas, gdy kursor myszy najeżdża na element
mouseleave metoda jest wywoływana wówczas, gdy kursor myszy zjeżdża z elementu
mousemove metoda jest wywoływana wówczas, gdy kursor myszy zmienia położenie wewnątrz elementu

Powyższa tabela zawiera jedynie część metod zdarzeniowych, z jakich możemy korzystać w jQuery. Jeśli ktoś chciałby zapoznać się z resztą, odsyłam do strony http://api.jquery.com/category/events/.

Zdarzenia złożone

Właściwie mowa tu będzie o złożonych programach obsługi zdarzeń. Są to rozbudowane zdarzenia – programy, dodane przez jQuery, które przechwytują kombinacje działań użytkownika, reagując na nie kilkoma funkcjami. Mogło to zabrzmieć zawile, ale za chwilę wszystko powinno być jasne.

Toggle(function(){…},function(){…},function(){…},…)

$(‘#element’).toggle(function() {
alert(‘Kliknięcie nieparzyste’);
, function(){
alert(‘Kliknięcie nieparzyste’);
});

Metoda toggle() jest pewnego rodzaju przełącznikiem. Bezparametrowe wywołanie tej funkcji, na wybranym elemencie, zmienia jego stan widoczności. Zatem jeżeli element był ukryty, to stanie się widoczny, a gdy był widoczny to stanie się ukryty.

Podobnie zresztą działa funkcja toggleClass(‘klasa’). Metoda ta sprawdza za nas, czy wybrany element posiada wybraną klasę oraz czy automatycznie ją dodaje lub usuwa.

$(‘#element’).toggleClass(‘new-class’);

Jednakże metodę toggle() można również wywołać z argumentami. Argumentami tej metody stają się wówczas funkcje(jedna lub więcej). Pierwsze kliknięcie na element, do którego przypięliśmy metodę toggle(), spowoduje wywołanie pierwszej funkcji, drugie kliknięcie wywoła drugą funkcję itd. Po wywołaniu wszystkich metod znów wywoła się metoda pierwsza itd.

Hover(function(){…}, function(){…})

Czasem może się zdarzyć sytuacja, w której będziemy musieli użyć zdarzenia mouseenter i mouseleave. Załóżmy, że chcemy, aby po najechaniu na jakiś element został on wyróżniony(przez to nadajemy mu odpowiednią klasę), a po opuszczeniu przez mysz chcemy mu przywrócić stan pierwotny. Intuicyjnie użylibyśmy metod zdarzeniowych mouseenter, aby obsłużyć najechanie na element i mouseleave, aby obsłużyć opuszczenie elementu. Być może kod nie byłby skomplikowany, ale tą czynność można wykonać znacznie szybciej za pomocą metody hover();

$(‘#element’).hover(function() {
$(this).addClass(‘new-class’)}
, function(){
    $(this).removeClass(‘new-class’)
});

Metoda hover() przyjmuje dwa argumenty, które w rzeczywistości są funkcjami. Pierwsza funkcja zostaje wywołana, kiedy kursor myszy znajdzie się nad wybranym elementem, a druga kiedy kursor opuści ten element.

Dodatkowo, pewną nową rzeczą, która występuje w tym przykładzie, jest odniesienie do bieżącego elementu za pomocą wyrażenia $(this). W rzeczywistości pod zmienną $(this) tworzony jest obiekt jQuery, który odpowiada elementowi z kontekstu wywołania funkcji. W naszym przykładzie będzie to zatem element o identyfikatorze ‘element’.

Kolejność występowania zdarzeń

W jQuery wystąpienie zdarzenia nie kończy się na elemencie, dla którego je zarejestrowaliśmy. Występuje tu propagacja zdarzeń, co oznacza, że zdarzenie zostaje przesyłane od elementu, leżącego na samym dole hierarchii drzewa DOM, do góry, czyli do elementów bardziej ogólnych, zawierających dany element.

Załóżmy, że mamy daną strukturę:

<div id=”div1”>
<div id=”div2”>
<p id=”p1”></p>
</div>
</div>

a dla elementu p o identyfikatorze “p1” zarejestrowaliśmy zdarzenie „click”. Wówczas to on jako pierwszy zostanie poinformowany o wystąpieniu tego elementu, drugi będzie element <div> o id=”div2”, a następny <div> o id=”div1”.

Niestety, czasem takie zachowanie niesie ze sobą niepożądane efekty, które postaram się przedstawić w kolejnym przykładzie:

<div id="kontener">
    <p class="paragraf">paragraf 1</p>

    <p class="paragraf">paragraf 2</p>

    <p class="paragraf">paragraf 3</p>
</div>


$(document).ready(function(){
$('.paragraf').click(function(){alert('klik');});

$('#kontener').click(function(){
    $('#kontener .paragraf').toggle();
});

});

Po kliknięciu w obszar <div> wszystkie elementy o klasie „paragraf” są ukryte. Niestety, nawet po kliknięciu w element <p> i wywołaniu zdarzeniu jej przypisanemu, cały obszar <div> również jest ukryty. A wszystko to za sprawą propagacji zdarzeń. Zdarzenie jest najpierw obsługiwane przez element <p>, a następnie przekazywany ku górze, aż dojdzie do elementu <div> i wywoła na nim obsługę kolejnego zdarzenia.

Problem ten można rozwiązać, dodając specjalny parametr do funkcji wywołującej zdarzenie „event”. Jedną z informacji, jaką nam on dostarcza, to położenie kursora myszy w chwili wystąpienia zdarzenia.

$(document).ready(function(){
$('.paragraf').click(function(){alert('klik');});

$('#kontener').click(function(event){
    if(event.target==this)
{
    $('#kontener .paragraf').toggle();
}
});
});

Jak widać, zmieniliśmy wcześniejszy przykład, dodając do niego parametr event. Następnie, w chwili wystąpienia zdarzenia, sprawdzamy, czy element, który otrzymał zdarzenie jako pierwszy, jest elementem o id=”kontener”.

event.target==this.

Takie zabezpieczenie daje nam pewność, że nasz kod wykona się tylko wówczas, gdy zostanie klikniemy na zdefiniowany przez nas element, a nie jakikolwiek z jego elementów potomnych.

Ponadto, obiekt omawianego przez nas zdarzenia event, udostępnia nam metodę, która zatrzymuje dalszą propagację zdarzenia. Metoda ta nosi nazwę .stopPropagation().

$('.paragraf').click(function(event){
alert('klik');
event.stopPropagation();
});

 Po jej wywołaniu, elementy położone wyżej w hierarchii względem elementu .paragraf nie zostaną poinformowane o wystąpieniu zdarzenia.

Delegacja zdarzeń

Jest to prosta technika, polegająca na propagowaniu zdarzeń w taki sposób, aby wiele elementów mogło z niego skorzystać. W delegacji zdarzeń często używa się metody .is(). Zwraca ona wartość true lub false w zależności od tego, czy element, na którym wywołujemy metodę dopasowany jest do argumentu, którym może być dowolny selektor.

Zobaczmy to na poniższym przykładzie:

<div id="kontener">
    <p class="paragraf" id=”p1”>paragraf 1</p>
    <p class="paragraf" id=”p2”>paragraf 2</p>
    <p class="paragraf" id=”p3”>paragraf 3</p>
</div>


$(document).ready(function(){
$('#kontener).click(function(event){
if($(event.target).is(‘.paragraf’))
{
  if(event.target.id==’p1’)
{
alert(‘kliknąłeś p1’);
}

  if(event.target.id==’p2’)
{
alert(‘kliknąłeś p2’);
}

  if(event.target.id==’p3’)
{
alert(‘kliknąłeś p3’);
}
event.stopPropagation();
}
 });
});

Zdarzenie click w tym przypadku podpięliśmy do zewnętrznego elementu drzewa DOM, względem elementów <p>, czyli do elementu <div>. Dzięki tej opcji oraz propagacji zdarzeń, nawet kliknięcie  w element <p> wywoła nam zdarzenie.

Następnie sprawdzamy warunek:

if($(event.target).is(‘.paragraf’))

Dzięki niemu możemy ustalić, czy element, na którym zostało wywołane zdarzenie, posiada klasę .paragraf. Jeśli tak, to następnie sprawdzamy, który to był z elementów <p> if(event.target.id==’p1’) itd.

Jak widać, cały mechanizm nie jest trudny, a dodatkową jego zaletą jest fakt, że wszystko mamy obsłużone w jednej sprecyzowanej metodzie.

Podsumowanie

W tym artykule dowiedzieliśmy się, czym są zdarzenia oraz jak można je zarejestrować na stronie. Poznaliśmy złożone zdarzenia, takie jak toggle() czy hover(). Przyjrzeliśmy się również propagacji zdarzeń i jej wykorzystaniu w delegacji. Mam nadzieję, że to wszystko przybliżyło wam jQuery jeszcze bardziej i zachęciło do dalszej nauki w tym zakresie.