Mootools 1.1 - Element.Event.js
19 czerwca, 2007
Plik element.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, poskromimy klawiaturę przy użyciu JavaScript oraz zajmiemy się dodawaniem, usuwaniem i klonowaniem zdarzeń elementów ;)
W pliku element.event.js mamy zawarte 4 metody dla klasy Event oraz kilkanaście właściwości dla obiektów typu event, do tego dochodzi 6 metod klasy Element oraz trzy nowe zdarzenia i jedna metoda rozszerzająca klasę Function.
Zacznijmy od stworzenia zdarzenia onclick dla elementu.
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 przedstawiana sytuację:
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:
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.
Właściwości obiektu event
Obiekt 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:
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 się znalazł 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 :
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:
Warto jeszcze wspomnieć o właściwości wheel (event.wheel), zwracającej ilość obrotów kółkiem myszki no i o obiekcie keys.
Właściwość wheel zwraca wartość dodatnią przy obrocie kółkiem myszki "w górę" i ujemną wartość przy obrocie kółkiem myszki "w dół".
Obiekt keys pozwala nam rozszerzyć standardową liczbę nazwanych klawiszy o własne. Pod pojęciem nazwane klawisze rozumiem te klawisze, które reagują na zapis postaci:
event.key == 'nazwa_klawisza'.
Jak nazwać przykładowy klawisz swoją wybraną nazwą ?
Stosujemy zapis:
Event.keys.nazwa_klawisza = kod_klawisza;
Gdybyśmy chcieli w ten sposób nazwać klawisz enter (hipotetycznie oczywiście bo jest on już nazwany) to zapisalibyśmy:
Event.keys.enter = 13;
Operowanie na zdarzeniach
W tej części opiszę krótko jak dodawać, usuwać i klonować zdarzenia. Krótko bo z podobnymi funkcjami mieliśmy już do czynienia przy omawianiu pliku class.extras.js .
addEvent i addEvents
Metoda addEvent służy oczywiście dodawaniu zdarzeń do danego elementu. Metoda addEvents różni się od niej tym, że pozwala na dodanie kilku zdarzeń na raz. Składnie obu metod:
element.addEvent('typ_zdarzenia',function(){
//kod wykonywany przy zdarzeniu
});
element.addEvents({
'typ_zdarzenia': function(){
// kod funkcji
},
'typ_zdarzenia': function(){
// kodu funkcji
}
});
Przykładowo kod, który występował w jednym z moich poprzednich przykładów:
$('btn1').addEvent('mouseover',function(){
$E('a','linki2').setStyle('border','3px solid #F00');
});
$('btn1').addEvent('mouseout',function(){
$E('a','linki2').setStyle('border','none');
});
mogłem zastąpić poniższym kodem:
$('btn1').addEvents({
'mouseover': function(){
$E('a','linki2').setStyle('border','3px solid #F00');
},
'mouseout': function(){
$E('a','linki2').setStyle('border','none');
}
});
removeEvents
Metoda jest podobna do dwóch poprzednich z tą różnicą, że ta metoda usuwają zdarzenia elementu. Składnia tej metody jest prostsza niż w poprzednim wypadku:
element.removeEvents();
Powyższy kod usuwa wszystkie zdarzenia z danego elementu. Gdybyśmy chcieli usunąć tylko jedno zdarzenie to zapiszemy:
element.removeEvents('typ_zdarzenia1');
Od siebie jeszcze dodam, że do tej pory nie udało mi się dojść jak działa metoda removeEvent - wszystkie przykłady jej zastosowania jakie widziałem stanowiły długi kod więc patrząc na możliwości metody removeEvents wydaje mi się ona dobrym zastępcą metody removeEvent ;)
fireEvent
Metoda fireEvent pozwala na uruchomienie funkcji przypisanej do danego zdarzenia. Pobiera trzy argumenty - typ zdarzenia, argumenty dla uruchamianej funkcji (w wypadku gdy jest ich więcej niż jeden podajemy je jako tablicę) i opóźnienie wykonania tej funkcji:
element.fireEvent('typ_zdarzenia','argument','opóźnienie');
cloneEvents
Metoda cloneEvents służy do kopiowania zdarzeń jednego elementu do drugiego. Pozwala skopiować zarówno wszystkie zdarzenia jak i tylko jedno wybrane.
Składnia tej metody:
element.cloneEvent('element2');
Powyższy kod spowoduje skopiowanie wszystkich zdarzeń elementu element2 do elementu element.
element.cloneEvent('element2','click');
Powyższy kod sprawi, że skopiowane zostanie tylko zdarzenie onclick elementu element2 do elementu element.
Zdarzenia mouseenter i mouseleave
Te zdarzenia są wprost bezcenne w wypadku tworzenia rozwijanego menu opartego na liście nieuporządkowanej - zdarzenie mouseenter występuje w momencie najechania na dany element i nie jest wywoływane ponownie gdy najedziemy myszką na jeden z elementów potomnych tego elementu. Drugie zdarzenie występuje wtedy gdy opuścimy dany element (czyli obszar zajmowany także przez jego elementy potomne). Jak widać są to świetni zastępcy zdarzeń onmouseover i onmouseout w wielu sytuacjach.
Zdarzenie mousewheel
Zdarzenie to występuje w momencie obracania kółkiem myszki - wtedy można też odczytać ilość obrotów za pomocą właściwości wheel obiektu event.
bindWithEvent
Metoda bindWithEvent służy 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);
};
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...
Wpis ten jest rozszerzoną wersją artykułu o pliku event.js z kursu mootools 1.0 napisanym na potrzeby kursu mootools 1.1
W następnej części kursu zajmiemy się między innymi rozmiarami i pozycją elementów - omówię plik element.dimensions.js
Komentarze do wpisu "Mootools 1.1 - Element.Event.js":
1.
ajtuj napisał(a):
25 lipca 2007, 12:18:47
W przykładzie 5 zmieniłbym kod js tak aby utrwalić sobie ‘bindowanie’ :)
window.onload = function(){ var w = false; function textStyle(event){ var event = new Event(event); event.stop(); if($chk(window.opera) === true){ browser = event.shift; } else{ browser = event.control; } if(browser){ if (event.key == 'b') $('text').setStyle('font-weight','bold'); if (event.key == 'i') $('text').setStyle('font-style','italic'); if (event.key == 'u') $('text').setStyle('text-decoration','underline'); if (event.key == 'r') { $('text').setStyle('font-weight','normal'); $('text').setStyle('font-style','normal'); $('text').setStyle('text-decoration','none'); } } } if($chk(window.ie) == true){ var w = document.body; } else{ if($chk(window.gecko) === true || $chk(window.opera) === true){ var w = window; } } if(w){ w.onkeydown = textStyle.bindWithEvent(w); } }2.
Dziudek napisał(a):
25 lipca 2007, 12:40:55
ajtuj – dobra propozycja :) Mam tylko małe „ale” – nie powinno być linijki
var event = new Event(event);, bo metodabindWithEventwykonuje tą operację automatycznie :) Ale reszta ok. Dodam jako alternatywny kod JS z odpowiednim komentarzem :) Dzięki ;)Dodaj komentarz: