Magazyn T3
newsy, felietony, testy i tutoriale



Internet Maker

25/08/2008

AJAX Kurs od podstaw – jQuery

Więcej artykułów autorstwa »
Napisane przez: Włodzimierz Gajda
Tagi: ,
99-ajax_kurs_od_podstaw_-_jquery.gif

Biblioteka jQuery pozwala na operowanie drzewem DOM dokumentu przy użyciu zestawu selektorów. Elementy HTML wskazane odpowiednimi selektorami wzbogacamy o obsługę zdarzeń, wykorzystując do tego zestaw metod. Dzięki temu osiągamy pełną separację kodu HTML od JavaScriptu, a implementacja takich rozwiązań jak ajaksowe menu bez przeładowania lub ajaksowa wyszukiwarka bez przeładowania zajmuje zaledwie kilka linijek kodu.

Ładowanie treści po kliknięciu

Wykonanie menu, które nie będzie przeładowywało całej strony rozpoczynamy od załadowania zewnętrznego dokumentu (tj. pliku fragment-abba.html) do elementu o identyfikatorze {stala}#content{/stala} po wystąpieniu zdarzenia {stala}onclick{/stala}. Zadanie to zrealizuje następujący kod jQuery:

1
2
3
4
5
6
7
$(\'#a1\').click(function(){
   $(\'#content\').load(\'fragment-abba.html\');
});
<ol>
   <li id=\"a1\">ABBA</li>
</ol>
<div id=\"content\"></div>

Najpierw wybieramy element o identyfikatorze {stala}#a1{/stala}, któremu definiujemy zdarzenie {stala}onclick{/stala}:

1
2
3
$(\'#a1\').click(function(){
   ...
});

Wewnątrz obsługi zdarzenia występuje ładowanie zewnętrznego dokumentu fragment-abba.html do elementu o identyfikatorze {stala}#content: $(‘#content’).load(‘fragment-abba.html’);{/stala}

Kilka opcji menu

Jeśli menu zawiera kilka opcji:

1
2
3
4
5
6
<ol id=\"menu\">
   <li id=\"a1\">ABBA</li>
   <li id=\"a2\">AC DC</li>
   ...
</ol>
<div id=\"content\"></div>

wówczas definiujemy zdarzenie {stala}onclick{/stala} każdej opcji z osobna:

1
2
3
4
5
6
7
8
$(document).ready(function(){
   $(\'#a1\').click(function(){
      $(\'#content\').load(\'fragment-abba.html\');
   });
   $(\'#a2\').click(function(){
      $(\'#content\').load(\'fragment-ac-dc.html\');
   });
});

Menu ol/li/a

Opcje menu należy przekształcić w hiperłącza {stala}a{/stala}:

1
2
3
4
5
6
<ol>
   <li><a href=\"fragment-abba.html\">ABBA</a></li>
   <li><a href=\"fragment-ac-dc.html\">AC DC</a></li>
   ...
</ol>
<div id=\"content\"></div>

W tym przypadku stosujemy selektor wybierający element o zadanej wartości atrybutu. W ten sposób kod jQuery przyjmie postać:

1
2
3
4
5
6
7
8
9
10
$(document).ready(function(){
   $(\'a[href=\"fragment-abba.html\"]\').click(function(){
      $(\'#content\').load(\'fragment-abba.html\');
      return false;
   });
   $(\'a[href=\"fragment-ac-dc.html\"]\').click(function(){
      $(\'#content\').load(\'fragment-ac_dc.html\');
      return false;
   });
});

Instrukcje {stala}return{/stala} zapewniają, że kliknięcie hiperłącza nie będzie powodowało przeładowania strony.

Ajaksowe menu działające po wyłączeniu JavaScriptu

Witryna z menu, które nie przeładowuje strony, wymaga przygotowania każdej podstrony w dwóch wersjach: pełnej i okrojonej. Strona w wersji okrojonej zawiera przedrostek fragment-. Jeśli na przykład witryna zawiera dwie opcje menu, które mają ładować pliki abba.html oraz ac_dc.html, to należy przygotować cztery pliki:

1
2
3
4
abba.html
fragment-abba.html
ac_dc.html
fragment-ac_dc.html

W menu witryny, w atrybutach {stala}href {/stala}stosujemy nazwy pełnych stron (tj. bez przedrostka fragment-):. Dzięki temu witryna będzie działała po wyłączeniu JavaScriptu:

1
2
3
4
5
6
<ol>
   <li><a href=\"abba.html\">ABBA</a></li>
   <li><a href=\"a_dc.html\">AC DC</a></li>
   ...
</ol>
<div id=\"content\">

W powyższym kodzie ujawnia się cały urok rozwiązania stosującego jQuery. Jest to bowiem zwykłe menu, jakie byśmy przygotowali wykonując statyczne pliki HTML.

Modyfikację hiperłączy menu w takie, które nie przeładowują strony zapewnia kod zawarty w pliku menu.js (plik ten należy oczywiście dołączyć do każdej pełnej podstrony):

1
2
3
4
5
6
7
8
$(document).ready(function(){
   $(\'a\').click(function(){
   $(\'#content\').load(
      \'fragment-\' + $(this).attr(\'href\')
   );
   return false;
   });
});

Kolejno:

  • wybieramy wszystkie hiperłącza{stala} $(‘a’){/stala},
  • ustalamy obsługę zdarzenia {stala}onclick{/stala},
  • w obsłudze zdarzenia {stala}onclick{/stala} do elementu posiadającego identyfikator {stala}#content{/stala} ładujemy zewnętrzny plik,
  • adres url pobieranego pliku zewnętrznego powstaje z adresu odczytanego z atrybutu {stala}href{/stala} klikniętego hiperłącza {stala}this{/stala} przez dodanie prefiksu fragment-,
  • kliknięcie hiperłącza nie może powodować przeładowania strony ({stala}return false{/stala}).

Wyszukiwarka

Wyszukiwarka ajaksowa, której użycie nie przeładowuje strony wykorzystuje formularz oraz element {stala}#wyniki{/stala}:

1
2
3
4
5
<form action=\"index.php\" method=\"get\">
   <input id=\"sz\" name=\"szukaj\" />
   <input type=\"submit\" value=\"szukaj\" />
</form>
<div id=\"wyniki\"></div>

Działanie wyszukiwarki definiuje następujący kod JavaScript:

1
2
3
4
5
6
7
8
$(document).ready(function(){
   $(\'#wyniki\').hide();
   $(\'form\').submit(function(){
      $(\'#wyniki\').load(\'server.php?co=\' + $(\'#sz\').attr(\'value\'));
      $(\'#wyniki\').show();
      return false;
   });
});

Kolejno:

  • zaraz po załadowaniu dokumentu ukrywamy element {stala}#wyniki{/stala} (metoda {stala}hide(){/stala}),
  • ustalamy obsługę zdarzenia {stala}onsubmit{/stala} elementu form,
  • obsługa zdarzenia polega na załadowaniu zewnętrznego dokumentu do elementu {stala}#wyniki{/stala} (metoda {stala}load(){/stala}) i pokazaniu elementu {stala}#wyniki{/stala} (metoda {stala}show(){/stala}),
  • adres URL pobieranego elementu powstaje przez dodanie na końcu adresu {stala}sever.php?co={/stala} tekstu wprowadzonego w formularzu do elementu o identyfikatorze {stala}#sz{/stala},
  • instrukcja {stala}return false{/stala} zakazuje przeładowania strony.

Wykorzystując odwołania kaskadowe, obsługę zdarzenia {stala}onsubmit{/stala} można zakodować następująco:

1
$(\'#wyniki\').load(\'server.php?co=\' + $(\'#sz\').attr(\'value\')).show();

Podana wyszukiwarka, podobnie jak opisane wcześniej menu, działa także po wyłączeniu obsługi JavaScript.

Cechy jQuery

Zasadniczą zaletą biblioteki jQuery jest oddzielenie struktury dokumentu (tj. XHTML) od zachowania (tj. JavaScript). Strona WWW, która stosuje jQuery nie zawiera w kodzie HTML żadnych zdarzeń, a jedynie elementy XHTML ewentualnie wzbogacone o identyfikatory oraz klasy. Obsługę zdarzeń elementów HTML definiujemy całkowicie w Java-Scripcie, wykorzystując do tego funkcje i metody biblioteki jQuery.

Pierwszym etapem pracy jest wskazanie o który element HTML chodzi. Zadanie to realizujemy przy użyciu selektorów. Szczególnie wygodne są selektory, których składnia jest identyczna ze składnią selektorów CSS. Dzięki temu korzystanie z jQuery jest wygodne i naturalne.

Po wybraniu elementów odpowiednim selektorem przechodzimy do zdefiniowania zachowania elementu. Do tego służą metody klasy jQuery. Zapewniają one łatwy dostęp do zawartości, atrybutów oraz zdarzeń elementu lub elementów wybranych przy użyciu selektora. Co ciekawe, w przypadku gdy selektor pasuje do wielu elementów, wszystkie pasujące elementy będą przetwarzane iteracyjnie.

Warto zwrócić uwagę na fakt, że asynchroniczne pobieranie dokumentów przy użyciu Ajaksa sprowadza się do wywołania jednej metody, {stala}load(){/stala}, której parametrem jest adres URL pobieranego dokumentu.

Naukę jQuery podzielimy na kilka następujących części:

  • uruchomienie i analiza pierwszego skryptu,
  • selektory CSS,
  • wymiana treści i wyglądu,
  • zdarzenia,
  • zagadnienia dodatkowe.

Całość zakończy się omówieniem dwóch przykładów praktycznych: menu, które działa bez przeładowania dokumentu, oraz wyszukiwarki.

Prezentowany opis nie wyczerpuje wszystkich możliwości jQuery. Pełna dokumentacja, tutoriale, przykłady oraz najnowszą wersję biblioteki jQuery znajdziemy na stronie http://jquery.com.

Podstawy

Pierwszy dokument HTML stosujący jQuery

Biblioteka jQuery jest dołączana do stron WWW jako zewnętrzny plik JavaScript, a zatem nie wymaga instalacji żadnego oprogramowania. Po dołączeniu do dokumentu HTML pliku jquery-1.2.3.js uzyskujemy dostęp do obiektów i metod biblioteki jQuery.

Zasadniczą rolę odgrywa metoda {stala}ready(){/stala} klasy jQuery. Jest ona wywoływana po kompletnym załadowaniu strony, a zatem w jej treści możemy operować pełnym modelem DOM dokumentu. Wewnątrz funkcji {stala}ready(){/stala} definiujemy anonimową funkcję, która zostanie wywołana po zakończeniu ładowania dokumentu. W treści anonimowej funkcji możemy umieścić dowolny kod, np. wywołanie okna informacyjnego {stala}alert(){/stala}:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<html>
   <head>
      <title>Przykład 1-1</title>
      <script type=\"text/javascript\" src=\"jquery-1.2.3.js\"></script>
      <script type=\"text/javascript\">
      $(document).ready(function(){
         alert(\'Witaj\');
      });
      </script>
   </head>
<body>
<p>Lorem ipsum dolor sit amet!</p>
</body>
</html>

Obsługa zdarzenia onclick elementu p

Wspomniana na początku separacja zachowania (tj. JavaScript) od struktury (tj. HTML) polega na tym, że wewnątrz elementu body nie występują żadne zdarzenia JavaScript. Zdarzenie {stala}onclick{/stala} akapitu {stala}p{/stala}, które w tradycyjnym dokumencie HTML/JavaScript opisalibyśmy jako:

1
<p onclick=\"alert(\'Witaj\')\">Lorem</p>

przy użyciu jQuery definiujemy stosując selektor {stala}’p’ {/stala}oraz metodę {stala}click(){/stala}, w której umieszczamy wywołanie funkcji {stala}alert(){/stala}:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<html>
   <head>
      <title>Przykład 1-2</title>
      <script type=\"text/javascript\" src=\"jquery-1.2.3.js\"></script>
      <script type=\"text/javascript\">
      $(document).ready(function(){
         $(\'p\').click(function(){
            alert(\'Witaj\');
         });
      });
      </script>
   </head>
<body>
<p>Lorem ipsum dolor sit amet!</p>
</body>
</html>

Składnia jQuery

Zagadkowo wyglądający {stala}${/stala} w kodzie powyższych przykładów jest aliasem do funkcji o nazwie {stala}jQuery(){/stala}. Powyższy przykład możemy zapisać jako:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<html>
   <head>
      <title>Przykład 1-3</title>
      <script type=\"text/javascript\" src=\"jquery-1.2.3.js\"></script>
      <script type=\"text/javascript\">
      jQuery(document).ready(function(){
         jQuery(\'p\').click(function(){
            alert(\'Witaj\');
         });
 
      });
      </script>
   </head>
<body>
<p>Lorem ipsum dolor sit amet!</p>
</body>
</html>

W odróżnieniu od Pascala czy C++ w języku JavaScript znak {stala}${/stala} jest dozwolony w identyfikatorach funkcji.

Analizując składnię powyższego przykładu powiemy, że w skrypcie występuje funkcja {stala}jQuery(){/stala} wywołana z parametrem document:

1
jQuery(document)

Funkcja ta zwraca obiekt, na rzecz którego wywołujemy metodę {stala}ready{/stala}:

1
2
3
jQuery(document).ready(
   ...
);

Parametrem metody {stala}ready(){/stala} jest funkcja anonimowa, tj. taka, która nie otrzymała nazwy. Jej definicja występuje w miejscu wywołania:

1
2
function(){
}

W treści funkcji może występować dowolny kod. W powyższym przykładzie było to wywołanie funkcji {stala}jQuery(){/stala} z parametrem ‘p’. Zwróconemu obiektowi wywołaliśmy metodę {stala}click(){/stala}, której parametrem jest funkcja anonimowa wywołująca okno dialogowe {stala}alert(){/stala}:

1
2
3
jQuery(\'p\').click(function(){
   alert(\'Witaj\');
});

Element

Do wyboru wszystkich elementów zadanego typu służy selektor będący nazwą elementu. Akapity wybierzemy selektorem {stala}p{/stala}, sekcje div – selektorem {stala}div{/stala}, tabele – selektorem {stala}table{/stala}.

Skrypt:

1
2
3
4
5
6
7
$(document).ready(function(){
   $(\'p\').click(function(){
      alert(\'kliknięto p\');
   });
});
----------------------------
<p>Lorem...</p>

przypisze obsługę zdarzenia {stala}onclick{/stala} wszystkim akapitom {stala}p{/stala} występującym w dokumencie.

W powyższym przykładzie fragment znajdujący się przed linią jest kodem JavaScript, zaś dolny fragment – kodem HTML. Wszystkie kolejne przykłady zostały przedstawione w podobnej, skróconej formie.

Warto zwrócić uwagę, że podany przykład będzie działał analogicznie do stylów CSS. Jeśli w stylach CSS wpiszemy regułę:

1
2
3
p {
   color: blue;
}

to wszystkie akapity staną się niebieskie. Podobnie, selektor {stala}p{/stala} w jQuery:

1
2
3
$(\'p\').click(function(){
   alert(\'kliknięto p\');
});

spowoduje, że wszystkie elementy {stala}p{/stala} otrzymają obsługę zdarzenia {stala}onclick{/stala}.

Identyfikator

Jeśli element HTML zawiera identyfikator id, wówczas stosujemy selektor składający się ze znaku # oraz identyfikatora:

1
2
3
4
5
6
7
$(document).ready(function(){
   $(\'#tresc\').click(function(){
      alert(\'kliknięto #tresc\');
   });
});
----------------------------
<p id=\"tresc\">Lorem</p>

Klasa

Selektor elementów wzbogaconych o klasę składa się z kropki i nazwy klasy:

1
2
3
4
5
6
7
$(document).ready(function(){
   $(\'.inny\').click(function(){
      alert(\'kliknięto .inny\');
   });
});
----------------------------
<p class=\"inny\">Lorem</p>

Wartość atrybutu

Selektor:

1
a[href=\"ipsum.html\"]

odnosi się do elementu {stala}a{/stala}, którego atrybut {stala}href{/stala} przyjmuje wartość {stala}ipsum.html{/stala}:

1
<a href=\"ipsum.html\">ipsum</a>

Zatem kod:

1
2
3
4
5
6
7
8
9
10
11
$(document).ready(function(){
   $(\'a[href=\"ipsum.html\"]\').click(function(){
      alert(\'kliknięto ipsum.html\');
   });
});
----------------------------
<ol>
   <li><a href=\"lorem.html\">lorem</a></li>
   <li><a href=\"ipsum.html\">ipsum</a></li>
   <li><a href=\"dolor.html\">dolor</a></li>
</ol>

będzie ustalał obsługę zdarzenia {stala}onclick{/stala} wyłącznie środkowego hiperłącza.

Zmiana treści i wyglądu

Dostęp do treści elementu

Dostęp do treści elementu zapewnia metoda {stala}html(){/stala}. Wywołana bez parametru zwraca bieżącą treść elementu. Wywołana z parametrem ustala nową treść.

Jeśli metodę {stala}html(){/stala} wywołamy na rzecz klikniętego akapitu, wówczas kliknięcie akapitu będzie powodowało zmianę treści elementu:

1
2
3
4
5
6
7
$(document).ready(function(){
   $(\'p\').click(function(){
      $(this).html(\'one, two, ...\');
   });
});
----------------------------
<p>Lorem</p>

Dostęp do klikniętego akapitu wewnątrz metody {stala}click{/stala} umożliwia {stala}this{/stala} – referencja do obiektu, który wygenerował zdarzenie.

Zmiana stylu

Styl elementu zmienimy metodą {stala}css(){/stala}, która pobiera dwa parametry: nazwę właściwości oraz wartość:

1
2
3
4
5
6
7
$(document).ready(function(){
   $(\'p\').click(function(){
      $(this).css(\'color\', \'yellow\');
   });
});
----------------------------
<p>Lorem</p>

Wadą powyższego rozwiązania jest połączenie dwóch języków: CSS oraz JavaScript. Wygodniej będzie do zmiany formatu wykorzystać klasy CSS oraz metody {stala}addClass(){/stala} i {stala}removeClass(){/stala}.

Dodanie i usunięcie klasy

Każdy element wybrany selektorem możemy dynamicznie wzbogacić o klasę. Umożliwia to metoda {stala}addClass(){/stala}. Poniższy przykład jest rozbity na trzy języki: CSS, JavaScript oraz HTML:

1
2
3
4
5
6
7
8
9
10
.inny {
   color: yellow;
} ----------------------------
$(document).ready(function(){
   $(\'p\').click(function(){
      $(this).addClass(\'inny\');
   });
});
----------------------------
<p>Lorem</p>

Aby usunąć klasy wywołujemy {stala}removeClass(){/stala}:

1
2
3
4
5
6
7
8
9
10
.inny {
   color: yellow;
} ----------------------------
$(document).ready(function(){
   $(\'p.inny\').click(function(){
      $(this).removeClass(\'inny\');
   });
});
----------------------------
<p>Lorem</p>

Zdarzenia

Biblioteka jQuery zapewnia dostęp do pełnego zestawu zdarzeń HTML. Na przykład obsługę zdarzeń {stala}onmouseover{/stala} oraz {stala}onmouseout{/stala} zdefiniujemy metodami {stala}mouseover(){/stala} oraz {stala}mouseout(){/stala}:

1
2
3
4
5
6
7
8
9
10
11
12
13
.inny {
   color: yellow;
} ----------------------------
$(document).ready(function(){
   $(\'p\').mouseover(function(){
      $(this).addClass(\'inny\');
   });
   $(\'p\').mouseout(function(){
      $(this).removeClass(\'inny\');
   });
});
----------------------------
<p>Lorem</p>

zaś zdarzenie {stala}ondblclick{/stala} metodą {stala}dblclick(){/stala}:

1
2
3
4
5
6
7
$(document).ready(function(){
   $(\'p\').dblclick(function(){
      $(this).css(\'text-decoration\', \'underline\');
});
});
----------------------------
<p>Lorem</p>

Duża część funkcji odpowiedzialnych za zdarzenia może być wywoływana na dwa sposoby. Pierwszym sposobem jest wywołanie z parametrem, którym jest funkcja:

1
2
3
$(\'p\').click(function(){
   ...
});

Takie wywołanie definiuje funkcję obsługi zdarzenia. Drugi sposób wywołania to wywołanie bezparametrowe: {stala}$(‘p’).click();{/stala}. Powoduje ono uruchomienie zdarzenia (ang. trigger).

Automatyczna iteracja

Jak już zostało powiedziane, selektor jQuery obejmuje swoim działaniem wszystkie wybrane elementy. Jeśli użyjemy selektora li:

1
2
3
4
5
6
7
8
9
10
$(document).ready(function(){
   $(\'li\').css(\'color\', \'blue\');
});
----------------------------
<ul>
   <li>one</li>
   <li>two</li>
   <li>three</li>
   <li>four</li>
</ul>

to przetwarzaniu będą podlegały wszystkie elementy listy. Każdy z nich stanie się niebieski. Nie wpisujemy ręcznie żadnej iteracji (np. pętli {stala}for{/stala}). Jest ona wykonywana podobnie jak w CSS automatycznie dla wszystkich elementów pasujących do selektora.

Kaskada

Większość metod jQuery zwraca w wyniku obiekt {stala}jQuery{/stala}. Pozwala to na tworzenie kaskadowych wywołań metod:

1
2
3
4
5
6
7
8
9
10
$(document).ready(function(){
   $(\'li\').css(\'color\', \'yellow\').append(\'- read more\').css(\'background\', \'black\');
});
----------------------------
<ul>
   <li>one</li>
   <li>two</li>
   <li>three</li>
   <li>four</li>
</ul>

Powyższy kod jQuery możemy równoważnie zapisać jako trzy osobne wywołania:

1
2
3
$(\'li\').css(\'color\', \'yellow\');
$(\'li\').append(\' - read more\');
$(\'li\').css(\'background\', \'black\');

Odczyt atrybutów

Dostęp do atrybutów zapewnia metoda {stala}attr(){/stala}, której parametrem jest nazwa atrybutu HTML:

1
2
3
4
5
6
7
8
9
10
11
$(document).ready(function(){
   $(\'input\').focus();
   $(\'input\').keyup(function(){
      $(\'div\').html($(\'input\').attr(\'value\'));
   });
});
----------------------------
<form action=\"#\" method=\"post\">
      <input type=\"text\" name=\"imie\" value=\"\" />
</form>
<div></div>

Wywołanie:

1
$(\'input\').attr(\'value\')

odczytuje atrybut {stala}value{/stala} elementu {stala}input{/stala}:

1
<input name=\"\" value=\"\" />

Pierwsza instrukcja:

1
$(\'input\').focus();

uruchamia zdarzenie {stala}onfocus{/stala} dla elementu {stala}input{/stala}. Dzięki niej bezpośrednio po otworzeniu dokumentu w przeglądarce kursor będzie znajdował się w polu edycyjnym formularza.

Ajax, czyli asynchroniczne ładowanie pliku

Do załadowania zewnętrznego pliku służy {stala}load(){/stala}:

1
2
3
4
5
$(document).ready(function(){
   $(\'#content\').load(\'lorem.html\');
});
----------------------------
<div id=\"content\"></div>

Działa ona w oparciu o obiekt {stala}XMLHttpRequest{/stala}. Dokument, którego adres URL jest podany jako parametr jest pobierany asynchronicznie w tle (Ajax).

Może Cię zainteresować:

  1. AJAX Kurs od podstaw – wymiana fragmentu strony
  2. AJAX Kurs od podstaw – interakcja AJAX – PHP
  3. AJAX Kurs od podstaw – interaktywne aplikacje WWW


O autorze

Włodzimierz Gajda





1 komentarz


  1. Bardzo, fajny artykuł ale powinna być opcja wydrukowania całego newsa…

    Pozdrawiam



Zostaw odpowiedź

Twój adres nie zostanie opublikowany. Wymagane pola są oznaczone *

*

Możesz używać tych tagów i atrybutów HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">