MooTools 1.2 - elementy strony cz. 1
03 września, 2008
Niezwykle istotną sprawą przy tworzeniu skryptów jest możliwość łatwego poruszania się po drzewie dokumentu - w MooTools mamy kilka metod, które pozwalają nam na dostęp do różnych elementów względem innych elementów. Dodatkowo zapoznamy się bliżej z funkcją $$, która pozwala na selekcję kilku elementów naraz według określonych parametrów.
Dolary
Jak wiemy funkcja $ pozwala przede wszystkim na selekcję pojedynczego elementu według jego atrybutu id. W wypadku funkcji $$ możemy wyselekcjonować całe grupy elementów. W podstawowej wersji możemy dokonywać selekcji według tagów natomiast po dodaniu obsługi selektorów do frameworka możemy korzystać także z selektorów CSS. Zatem aby uzyskać dostęp do wszystkich obrazków na stronie zapiszemy:
$$('img');
Aby wybrać tylko obrazki posiadające klasę image:
$$('img.image');
Dodatkowo możemy stworzyć grupę elementów złożoną z kilku typów elementów - przykładowo aby wybrać wszystkie obrazki ze strony i linki z klasą link, zapisujemy:
$$('img', 'a.link');
Zatem jako kolejne argumenty możemy podawać kolejne selektory elementów. Dodatkowo jeżeli musimy wykonać jakąś operację na danym elemencie do którego mamy już uchwyt w postaci zmiennej i grupie innych elementów, które należy dopiero wyselekcjonować zapiszemy:
var el = $('element'); // fragment kodu $$(el, 'img');
Powyższy kod spowoduje stworzenie tablicy wszystkich obrazków ze strony i elementu posiadającego id "element". Jest to zdecydowane ułatwienie - nie musimy do kolekcji elementów dodawać w dalszym kodzie nowej pozycji lub tworzyć jakichś cech wspólnych dla danych elementów tylko po to by ułatwić sobie później selekcję w JavaScript.
Możliwości funkcji $$ są ogromne, ale prawdziwy ich urok poznamy dopiero przy omawianiu selektorów w dalszej części kursu.
Dolary inaczej
Swego rodzaju odpowiednikami funkcji $ i $$ są metody getElement, getElements oraz getElementById. Różnica polega na tym, że pozwalają na selekcję tylko jednej grupy elementów - zatem zapis taki jak:
$$('img', 'a.link');
Jest niemożliwy. Ale metody te mają inną zaletę - pozwalają na selekcję w obrębie danego elementu. Zatem zamiast stosować selektor:
$$('#testowy a.link');
Możemy wykorzystać zapis:
var el = $('testowy'); el.getElements('a.link');
Oczywiście zapis jest dłuższy, ale za to pozwala na stosowanie prostszych selektorów, a także wygląda w kodzie bardziej logicznie przy pętlach wykonujących selekcję elementów potomnych z kilku elementów. Metoda getElement różni się od getElements tym, że zwraca pierwszy element z całej kolekcji. Zatem jeżeli interesowałby nas tylko pierwszy link z klasą link w elemencie posiadającym id "testowy" zapiszemy:
var el = $('testowy'); el.getElement('a.link');
Jeżeli chodzi o metodę getElementById to powstała ona po to by uzupełnić funkcjonalność natywnej metody obiektu document związanej z DOM - getElementById pozwala ograniczyć zakres poszukiwań do danego elementu - wydawałoby się, że istnienie takiej metody jest mało sensowne, ponieważ atrybut id powinien być unikalny, ale metoda ta jest przydatna w sytuacji, gdzie musimy stwierdzić czy element o danym id jest elementem potomnym innego elementu:
var el = $('testowy'); var result = el.getElementById('link');
Zmienna result będzie zawierała uchwyt do elementu posiadającego id "link", jeżeli jest on potomkiem elementu posiadającego id "testowy" - w innym wypadku otrzymamy wartość null. Oczywiście można to też zbadać inaczej:
var result = $$('#testowy #link');
Jeżeli tablica result jest pusta to element "link" nie jest potomkiem elementu "testowy" - znów wszystko tak naprawdę dotyczy tego jak bardzo złożonych selektorów chcemy używać.
Dla podsumowania tej części wpisu przykład prezentujący różne rodzaje selekcji elementów wraz z użyciem funkcji i metod:
Warto zwrócić uwagę na równoważne zapisy oraz te zapisy, które nie zwracają żadnych elementów.
Bądź punktem odniesienia
Teraz chciałbym omówić metody, które pozwalają dokonywać selekcji elementów względem innego elementu w zakresie elementów sąsiednich, nadrzędnych i potomnych.
Na początek warto zapamiętać sobie trzy najważniejsze cechy wspólne wszystkich metod, które za chwilę omówię - jako argument mogą one opcjonalnie przyjmować typ elementu - zatem możemy dokładnie zdefiniować czego szukamy, zwłaszcza w momencie gdy mamy do dyspozycji rozbudowane selektory CSS. Druga cecha to fakt, że dla wszystkich rodzajów operacji istnieją zawsze dwa rodzaje selekcji - analogiczne do funkcji $ i $$. Zatem jedna metoda dokonuje selekcji pojedynczego elementu, a druga zwraca kolekcję elementów. Trzecia cecha - jeżeli element jaki chcieliśmy uzyskać nie istnieje to każda z tych metod zwraca wartość null.
Zacznijmy od wykrywania elementów nadrzędnych - do dyspozycji mamy metody getParent i getParents - już same nazwy mówią, która metoda jest odpowiednikiem funkcji $, a która odpowiednikiem funkcji $$. Zatem aby wykryć element nadrzędny wystarczy zapisać:
element.getParent();
Mając strukturę:
<div> <a href="http://blog.dziudek.pl">Link</a> </div>
I przyjmując, że zmienna element jest uchwytem do linka, uzyskalibyśmy uchwyt do elementu div.
Możemy też stworzyć taką strukturę elementów jak poniższa:
<div> <ul> <li><a href="http://blog.dziudek.pl">Link 1</a></li> <li><a href="http://miniblog.dziudek.pl">Link 2</a></li> </ul> </div>
Aby uzyskać uchwyty do elementów li, ul i div wystarczy zapisać:
element.getParents();
Gdzie zmienna element odnosi się do pierwszego lub drugiego linka.
To były podstawowe możliwości tych metod - a gdybyśmy chcieli szybko uzyskać uchwyt do elementu div z poziomu linka ?
W "starym" MooTools 1.11 musielibyśmy zapisać:
element.getParent().getParent().getParent();
A w naszym wypadku możemy zapisać:
element.getParents()[2];
Lub:
element.getParent('div');
Nie będę ukrywał, że drugi zapis jest o wiele bardziej elastyczny - przede wszystkim mamy pewność, że uzyskamy uchwyt do pierwszego nadrzędnego elementu typu div - możliwości jakie daje ten jeden niepozorny parametr we wszystkich funkcjach tego typu proszę przeanalizować samemu - na pewno w wielu wypadkach ułatwiają życie oraz często skracają kod skryptu.
Oczywiście w naszym wypadku zapis:
element.getParent('div');
Jest równoznaczny z zapisem:
element.getParents('div');
Ale w wypadku bardziej rozbudowanej witryny drugi zapis może zwrócić więcej elementów nadrzędnych typu div.
Pora na dzieci
Wiemy już jak odnaleźć rodziców naszego elementu - a co z dziećmi (potomkami) ? Istnieje metoda getChildren, która wyjątkowo nie ma odpowiednika getChild - w zamian mamy metody getFirst oraz getLast.
Metoda getChildren pozwala nam uzyskać kolekcję wszystkich elementów potomnych danego elementu lub tylko tych, które określono w podanym jako argument selektorze. Należy pamiętać, że elementy potomne rozumiemy jako te, które znajdują się bezpośrednio w danym elemencie. Skorzystajmy ze znanej już struktury elementów:
<div> <ul> <li><a href="http://blog.dziudek.pl">Link 1</a></li> <li><a href="http://miniblog.dziudek.pl">Link 2</a></li> </ul> </div>
W tym wypadku element div ma tylko jeden element potomny - listę nieuporządkowaną. I to ona będzie jedynym elementem kolekcji zwracanej przez:
element.getChildren();
Gdzie element to oczywiście uchwyt do naszego jedynego diva. Zatem zapis:
element.getChildren('li');
Zwróci nam wartość null. Gdybyśmy teraz zmienną element zdefiniowali jako:
var element = $$('ul')[0];
I wykorzystali metody getFirst i getLast:
element.getFirst(); element.getLast();
To uzyskalibyśmy dostęp odpowiednio do pierwszej i ostatniej pozycji listy nieuporządkowanej.
Zapis:
element.getFirst().getFirst('b'); element.getLast().getFirst('i');
Zwróci nam oczywiście wartości null, ponieważ elementy listy nie zawierają elementów kursywy i pogrubienia.
W poniższym przykładzie prezentuję kilka metod selekcji z użyciem poznanych dotychczas metod związanych z elementami nadrzędnymi i potomnymi:
Warto zwrócić uwagę na odwołanie do tablic elementów oraz auto-iterację.
Zostali sąsiedzi
Wiemy jak dokonać selekcji elementów położonych o poziom wyżej i niżej - istnieją też metody do selekcji elementów na tym samym poziomie - jedną z nich - getNext już poznaliśmy przy okazji omawiania zdarzeń elementów. Pozostały nam do omówienia jeszcze metody getAllNext, getPrevious oraz getAllPrevious.
Weźmy pod uwagę następującą strukturę elementów:
<div> <p>Tekst 1</p> <img src="obrazek.png" alt="obrazek" /> <p>Tekst 2</p> <p>Tekst 3</p> <ul> <li>Pozycja 1</li> <li>Pozycja 2</li> </ul> </div>
Gdybyśmy przyjęli, że naszym punktem odniesienia - zmienną element jest drugi paragraf tekstu to metoda:
element.getNext();
Zwróciłaby nam trzeci paragraf. Ta sama metoda z podanym argumentem:
element.getNext('ul');
Zwróci nam uchwyt do listy nieuporządkowanej. A oba te element (trzeci paragraf i listę nieuporządkowaną) naraz zwróci metoda:
element.getAllNext();
Z metodą getPrevious jest dokładnie na odwrót (działa "w górę"), zapis:
element.getPrevious();
Zwróci nam uchwyt do obrazka, a zapis:
element.getPrevious('p');
Zwróci nam pierwszy paragraf. No i oczywiście zapis :
element.getAllPrevious();
Zwróci nam oba te elementy (obrazek i pierwszy paragraf tekstu) naraz.
Celowo nie rozwodziłem się nad tymi metodami, ponieważ są one w swoich założeniach łudząco podobne do poznanych już metod - operują jedynie na innych poziomach elementów z otoczenia naszego punktu odniesienia jakim jest element wskazywany przez zmienną element.
Kilka przykładów selekcji umieściłem w poniższym przykładzie:
W ramach treningu
Proponuję przygotować zestaw odpowiedników poznanych metod działających jako samodzielne funkcje:
- getParent - $P,
- getParents - $PS,
- getChildren - $C
Należy pamiętać by uwzględnić fakt, że drugi argument (scope) jest w tych funkcjach jak najbardziej pożądany (no może poza funkcją getChildren). Do tego proponuję napisać funkcje:
- $I - selekcjonująca obrazki z dokumentu (opcjonalnie argument ograniczający zakres selekcji),
- $F -selekcjonująca formularze z dokumentu (opcjonalnie argument ograniczający zakres selekcji)
Podsumowanie
Wiemy już jak poruszać się po drzewie dokumentu, a nawet można by powiedzieć, że potrafimy po nim swobodnie skakać :) W następnej części poświęconej elementom dokumentu zajmiemy się atrybutami elementu i nowościami jakie pojawiły się w MooTools 1.2 w zakresie przechowywania informacji w elementach.
Komentarze do wpisu "MooTools 1.2 - elementy strony cz. 1":
1.
Bigismall napisał(a):
04 września 2008, 07:32:33
Jeśli o mnie chodzi, to $$() jest powodem dla którego zacząłem uzywać MooTools.
Świetny wpis. Idealny do zachęcenia ludzi do zapoznania się z tą biblioteką.
Dodaj komentarz: