mootools - event.js

29 kwietnia, 2007

Plik event.js to kolejny z elementów frameworka mootools, który z pewnością można zaliczyć do bardzo przydatnych. Wraz z tą częścią kursu nauczymy się likwidować dwa ważne problemy związane ze zdarzeniami, a na koniec poskromimy klawiaturę przy użyciu JavaScript ;)

W pliku event.js mamy zawartą klasę Event zawierającą 4 metody (i konstruktor oczywiście) oraz kilkanaście właściwości dla obiektów typu event.

Zacznijmy od stworzenia zdarzenia onclick.

Nasz kod będzie wyglądał następująco :

$('id_elementu').zdarzenie = function(){
    // kod jaki wykona się przy wystąpieniu zdarzenia
};

W wypadku gdy w kodzie zdarzenia będzie wykorzystywany obiekt klasy Event, nasz kod będzie wyglądał tak:

$('id_elementu').zdarzenie = function(event){
    var event = new Event(event);

    // kod jaki wykona się przy wystąpieniu zdarzenia
};

Przykładowo dodajmy do diva posiadającego id "div1" zdarzenie onclick, które spowoduje pokazanie się alertu z id tego diva:

$('div1').onclick = function(){
    alert(this.id);
};

Teraz umieśćmy w naszym divie drugi div posiadający id "div2" i dodajmy do niego w taki sam sposób zdarzenie onclick:

$('div2').onclick = function(event){
    alert(this.id);
};

Mając te dwa divy możemy przejść do omawiania metody stopPropagation.

stopPropagation

Metoda stopPropagation służy do obsługi sytuacji w której mamy jeden element umieszczony w drugim i oba z nich posiadają zdarzenie np.: onclick. Jak się pewnie orientujecie, taki układ spowoduje przy kliknięciu wewnętrznego diva, wykonanie obu funkcji / kodów JS przypisanych do zdarzeń elementów.

Dla zainteresowanych - dobry artykuł na ten temat.

Przyjmijmy, że nie chcemy aby po kliknięciu diva wewnętrznego pojawiał się także alert związany z kliknięciem zewnętrznego diva. Do osiągnięcia tego celu służy właśnie metoda stopPropagation - jej użycie spowoduje, że po kliknięciu zewnętrznego diva, zdarzenia onclick przypisane do elementów nadrzędnych względem niego, nie zostaną wykonane.

Zatem tworzymy w tym wewnętrznym divie button i dodajemy do niego id "button", a do zdarzenia window.onload dodajmy kod:

$('button').onclick = function(event){
    var event = new Event(event);
    event.stopPropagation();

    $('div2').onclick = function(event){
        var event = new Event(event);
        alert(this.id);
        event.stopPropagation();
    };

    alert('stopPropagation');
};

Po pierwsze - blokujemy wywoływanie zdarzeń elementów nadrzędnych w stosunku do buttona, a po drugie zmieniamy kod zdarzenia onclick elementu div2.

Przykład prezentujący przedstawianą sytuację:

PRZYKŁAD 1

preventDefault

Są takie elementy dokumentu HTML, które np.: po kliknięciu wykonują pewną określoną akcję zgodnie z podanymi atrybutami. Na przykład linki czy przycisk submit formularza. Czasami jednak, chcemy aby przed wysłaniem formularza dane zostały sprawdzone, albo chcemy by nasz link nie prowadził do danej strony według atrybutu href, a jedynie żeby ten atrybut był wykorzystywany jako zmienna dla skryptu.

Metoda preventDefault pozwoli nam na zatrzymanie domyślnych akcji onclick dla danych elementów i pozwoli w ten sposób na rozszerzenie możliwości elementów linków czy przycisków wysyłania formularzy. Warto zauważyć, że takie podejście do tych elementów zwiększy użyteczność naszych stron dla osób z wyłączoną obsługą JS. Przykładowo dla aktywnych linków z adresem "#" możemy stosować normalne adresy pozwalające wykonać dane operacje, normalnie dostępne przy użyciu efektów napisanych w JS. Podobnie z formularzami - przed wysłaniem można sprawdzić wszystkie dane, prosić użytkownika o potwierdzenie wprowadzonych danych itd. a użytkownicy bez JS zostaną poprowadzeni od razu do odpowiedniej strony...

W przykładzie posłużę się linkiem, który normalnie poprowadziłby nas do jakiejś strony, jednak dzięki zastosowaniu preventDefault pokazany zostanie jedynie alert z adresem linka.

Stwórzmy zatem w dokumencie dwa linki, posiadające id odpowiednio "link1" i "link2". Ustawmy też obu linkom atrybuty href "http://www.dziudek.jogger.pl".

Następnie dodajmy następujący kod JS:

$('link2').onclick = function(event){
    var event = new Event(event);

    event.preventDefault();

    alert(this.href);
};

Spowoduje on zatrzymanie wykonywania domyślnego zdarzenia dla drugiego linku i pokazanie alertu.

Powyższy przykład znajduje się na stronie poniżej:

PRZYKŁAD 2

stop

Jeśli chodzi o metodę stop, to nie będę się nad nią dłużej rozwodził ponieważ wykonuje ona dla danego zdarzenia po prostu dwie metody jednocześnie - preventDefault i stopPropagination. Zatem możemy po prostu dzięki niej skrócić zapis kodu gdy stosujemy obie metody jednocześnie dla danego eventu.

bindWithEvent

Metoda bindWithEvent to ostatnia z 4 metod udostępnianych przez klasę Event. Służy ona do automatycznego tworzenia obiektu event i wykorzystywania go w danej funkcji. Funkcja musi oczywiście pobierać jako argument dane zdarzenie...

Najlepiej będzie to wyjaśnić na podstawie przykładu. Mamy funkcję mysz:

function mysz(event){
    alert(event.client.x);
};

Służy ona do zwracania współrzędnej x położenia kursora myszy (o właściwościach obiektu Event będzie za chwilę).

Zatem powiążmy naszą funkcję ze zdarzeniem kliknięcia jakiegoś elementu. Tworzymy zmienną będącą referencją do danego obiektu:

element = $('id_elementu');

a następnie tworzymy powiązanie:

element.onclick = mysz.bindWithEvent(element);

W ten sposób nasze zdarzenie onclick danego elementu zostanie powiązane z funkcją mysz, która od tego momentu będzie się wykonywała po jego kliknięciu...

Zaletą wykorzystania tej metody jest fakt, że nie musimy tworzyć "ręcznie" nowego obiektu Event dla naszej funkcji...

Właściwości obiektu klasy Event

Obiekt klasy Event ma wiele właściwości powiązanych z położeniem kursora, czy wciskanymi klawiszami... Przejdźmy najpierw do pozycji kursora. Możemy pobierać współrzędne jego położenia na dwa sposoby - względem całej strony lub względem widocznej części strony.

Aby pobrać współrzędne kursora względem całej strony, wykorzystujemy dwie właściwości:

event.page.x;
event.page.y;

Aby zrobić to samo, ale względem widocznej części strony, korzystamy z właściwości:

event.client.x;
event.client.y;

Oczywiście w obu przypadkach x i y oznaczają odpowiednio współrzędną x i współrzędną y położenia kursora...

Przykład działania:

PRZYKŁAD 3

Zanim przejdziemy do obsługi klawiatury, omówię jeszcze dwie właściwości - target i relatedTarget. Właściwość target zwraca nam uchwyt do obiektu z jakim powiązane jest zdarzenie, natomiast właściwość relatedTarget występuje tylko w wypadku zdarzeń onmouseover i onmouseout. W wypadku zdarzenia onmouseover właściwość relatedTarget zwraca nam uchwyt do obiektu jaki opuścił kursor mysz przed znalezieniem się nad danym obiektem, natomiast przy zdarzeniu onmouseout zwracany jest uchwyt obiektu nad jakim znalazł się kursor po przejściu z danego obiektu dokumentu...

Oczywiście dostęp do obu właściwości otrzymujemy poprzez zapis:

event.target;

oraz

event.relatedTarget;

Aby lepiej zrozumieć działanie tych właściwości proponuję przetestować mały przykład :

PRZYKŁAD 4

A teraz przejdźmy już do klawiatury...

W przypadku obsługi klawiatury mamy do dyspozycji kilka właściwości :

event.shift;
event.control;
event.alt;
event.meta;
event.code;
event.key;

Pierwsze cztery zwracają wartość logiczną true, jeżeli użytkownik wcisnął dany klawisz (odpowiednio Shift, Ctrl, Alt lub metaklawisz). Pozostałe dwie właściwości zwracają ciągi znaków - kod wpisanego znaku lub sam znak (jako małą literę) , albo ewentualnie słowo ‘enter’, ‘up’, ‘down’, ‘left’, ‘ right’, ‘space’, ‘backspace’, ‘delete’ lub ‘esc’.

Oczywiście te możliwości można wykorzystać w aplikacjach np. przy skrótach klawiaturowych itd...

Przygotowałem przykład, który pozwala na zmianę stylu tekstu poprzez wciśnięcie odpowiedniej kombinacji klawiszy... Całość ogranicza się do sprawdzenia czy klawisz Ctrl został wciśnięty wraz z innym klawiszem.

Oczywiście pojawiła się mała trudność - na przykład kombinacja Ctrl + B powodowała pokazywanie zakładek w Firefoxie. Dlatego też należało zastosować zapis:

event.stop();

by uniknąć problemów z zarezerwowanymi przez przeglądarkę skrótami... Oczywiście należy pamiętać, że stosowanie skrótów pokrywających się ze skrótami przeglądarki może sfrustrować użytkownika, ponieważ odcina mu się dostęp do normalnej funkcjonalności tychże skrótów... Dlatego lepiej nie przesadzać ze stosowaniem skrótów...

Przykład o którym wspominałem wcześniej:

PRZYKŁAD 5

I to by było na tyle apropo pliku event.js - w następnej części kursu przejdziemy do pliku function.js, odpowiadającego za operowanie na funkcjach...

Naniosłem poprawki do ostatniego przykładu. Obecnie w IE i Firefoksie należy stosować skróty z Ctrl, a w Operze z Shiftem. Ponadto w IE nie działało zdarzenie window.onkeydown, które zastapiłem zdarzeniem document.body.onkeydown.

Komentarze do wpisu "mootools - event.js":

1. Pizzadude napisał(a):
29 kwietnia 2007, 13:24:51

(Komentarz zmodyfikowany 29.04.2007 o 13:27)

Kolenjy świetny wpis! ^^

Gryzie się ze skrótami w Operze:

Ctrl + b – pogrubienie,
Ctrl + i – kursywa,
Ctrl + u – podkreślenie,
Ctrl + r – przywrócenie początkowego stylu.

2. Pizzadude napisał(a):
29 kwietnia 2007, 13:25:52

Ups, popraw mój komentarz, na podglądzie był OK. oO

3. Dziudek napisał(a):
29 kwietnia 2007, 13:28:55

@Pizzadude – poprawione ;) Co do Opery – jeszcze muszę pokombinować – Firefoksowi wystarczyło event.stop(); Operze widać nie wystarcza ;)

4. heh napisał(a):
08 maja 2007, 10:42:29

Heh, problemik wyszło mootools 1.1. Właśnie to odkryłem, a zaraz idę do szkoły, ale rzut oka na dokumentację nowej wersji starczył, żeby zobaczyć, że zmiany są dość duże. Ostro pokombinowali w core, dodali klasy pozmieniali strukturę frameworka trochę, chociaż np. wszystko związane z Ajaxem pozostało takie samo (tylko kilka nazw pozmieniali). Trudno mi oceniać wszystkie te zmiany na szybko, ale na pewno będą problemy na przestawienie się, materiałów o nowej wersji jest dość mało i raczej suche.

5. Dziudek napisał(a):
08 maja 2007, 10:48:10

O nowej wersji frameworka wiem od dłuższego czasu, ale zaraz będzie mały „wpis nadzwyczajny”, bo trochę się sprawa skomplikowała ;]

6. pro napisał(a):
11 września 2007, 20:08:39

Przyszło mi robić refaktor systemy i zmieniam biblioteke na mootools. Event w mootools jest tak ubogi ze po prostu tragedia w porownaniu z prototype js trzeba korzystac ze zwyklego javascrip event i z eventa mootoolsa a tak w prototype js mam wszystko razem razy 2 porazka nie mam pojecia jak ja to teraz zrobie

Czy jest mozliwosc pobrania id elementu na ktorym zostal wykonany np mousedown event sam event jest dodany do calego dokumentu a ja potrzebuje id elementu na ktorym kliknieto w prototype mam to w event a w mootools ???

7. pro napisał(a):
11 września 2007, 20:11:38

acha przypomnialem sobie zwykly event.target.id tylko to nie chodzi na wszytskich przegladarkach ale safari mozna olac ;) jak trzeba

8. Dziudek napisał(a):
11 września 2007, 20:12:37

@pro – no też właśnie ;] event.target ;] nawet MooTools udostępnia do niego uchwyt więc nie wiem w czym problem zbytnio ;]

9. Dziudek napisał(a):
11 września 2007, 20:17:57

@pro - MooTools posiada pełne wsparcie dla target w Safari ;)

Dodaj komentarz:

Textile Lite włączony ( szczegółowy opis znaczników ):
*strong* | # lista numerowana | * lista wypunktowana | _em_ | __italic__ | "link":http:// | bq. cytat.