Strona używa cookies (ciasteczek). Dowiedz się więcej o celu ich używania i zmianach ustawień. Korzystając ze strony wyrażasz zgodę na używanie cookies, zgodnie z aktualnymi ustawieniami przeglądarki.    X

AJAX i jQuery (cz. 1)

W tym wpisie przedstawię jak załadować dane na stronę internetową bez jej przeładowywania. Wykorzystam w tym celu popularną bibliotekę JS o nazwie jQuery. Upraszcza ona operacje pobierania i wyświetlania danych na stronie i zapewnia działanie we wszystkich popularnych przeglądarkach.

Dzięki zastosowaniu AJAX'a możemy osiągnąć mnóstwo ciekawych rzeczy, ale przede wszystkim możemy przyspieszyć wyświetlanie informacji na stronie.

Zaczynamy

Na początek w sekcji head strony musimy załadować plik z biblioteką jQuery:<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>Od teraz możemy używać jQuery na stronie. Stwórzmy przykładową stronę:<div id="all"> <div id='header'> <h3>Nasze logo</h3> </div> <div id="menu"> <a href="index.html">Home</a> <a href="oferta.html">Oferta</a> <a href="uslugi.html">Usługi</a> <a href="kontakt.html">Kontakt</a> </div> <div id="content"> <p>Zawartość strony</p> </div> </div>

Po dodaniu kilku stylów CSS otrzymamy coś takiego:

Zakładam, że pliki podane w odnośnikach istnieją i zawierają zawartość dla odpowiednich stron. Tworząc strony, których działanie oparte jest na JS musimy wziąć pod uwagę, że nie wszyscy użytkownicy mają włączoną jego obsługę. W związku z tym powinniśmy zapewnić działanie strony również bez włączonego JS. Są na to rożne sposoby i w rożnych sytuacjach różne się sprawdzą. Na potrzeby tego ćwiczenia proponuje przyjąć następującą zasadę. Pliki podane w linkach w menu posiadają pełną strukturę strony. Dzięki temu po ich kliknięciu z wyłączonym JS wgra się normalnie strona. Oprócz tego w katalogu "ajax" znajdują się pliki o tych samych nazwach, które zawierają tylko treść, która ma się znaleźć w prawej kolumnie. Jest to oczywiście bardzo proste rozwiązanie i nie określił bym go jako najbardziej optymalne, ale nie wymaga znajomości, żadnego dodatkowego języka programowania.

Szybko i prosto

Cały kod jaki musimy teraz dodać w sekcji head to:<script type="text/javascript"> <!-- $(function(){ $("#menu a").click(function(e){ $("#content").load("ajax/"+$(this).attr('href')); e.preventDefault(); }) }) --> </script>

Kod $("#menu a").click(fn) przejmuje kliknięcie we wszystkie linki w elemencie o id równym "menu" i wykonuje funkcję podaną w nawiasach. Używamy tutaj funkcji anonimowej, w której wykorzystujemy metodę .load() dostępna w jQuery. Metodę "podpinamy" pod element, do którego ma być załadowana nowa treść. Jako argument podajemy adres url pliku do załadowania - pobieramy wartość atrybutu href linku i dodajemy do niego katalog "ajax". Na koniec wykonujemy e.preventDefault(); co zapobiega przejściu przeglądarki do adresu podanego w linku.

I to by było na tyle. Od teraz strony są ładowane bez przeładowywania strony.

Trochę więcej możliwości

jQuery nie ogranicza nas do tej jednej metody. Posiada szereg innych metod, które można wykorzystywać w zależności od potrzeb. Jest metoda $.getJSON, która ładuje obiekty JSON (JavaScript Object Notation), jest $.get(), która pobiera plik jako tekst, ale rozpoznaje pliki XML i zwraca drzewo DOM XML, jest metoda $.getScript(), która ładuje skrypty JS itd. Nie czas i miejsce, żeby je wszystkie opisywać. Przejdę teraz do opisu metody $.ajax().

Pełen zakres możliwości

Wszystkie metody wykorzystywane w jQuery do obsługi AJAX są ostatecznie odwzorowywane przez jQuery na metodzie $.ajax(). Ta metoda daje nam największy zakres możliwości i też największą kontrolę nad ładowaniem danach do i z serwera. Dzięki zastosowaniu tej metody możemy np wyświetlać wstępną informację o ładowaniu się treści, komunikat błędu itp.
Zmieńmy lekko strukturę naszej podstawowej strony. Dodamy do niej komunikat o ładowaniu strony oraz miejsce na tytuł strony:

<div id="all"> <div id="loader">Ładuję...</div> <div id='header'> <h3>Nasze logo</h3> </div> <div id="menu"> <a href="index.html">Home</a> <a href="oferta.html">Oferta</a> <a href="uslugi.html">Usługi</a> <a href="kontakt.html">Kontakt</a> </div> <div id="right"> <h4 id="title">Tytuł strony</h4> <div id="content"> <p>Zawartość strony</p> </div> </div> </div>

Element loader dzięki CSS ukrywamy, będziemy go pokazywać za pomocą JS podczas ładowania danych.

Tym razem oprócz ładowania treści strony będziemy też poobierać jej tytuł. Aby to zrobić zmienimy strukturę naszych plików, które ładujemy. Nie będą to już zwykłe pliki HTML, ale pliki przechowujące dane w postaci JSON. Dla przykładu plik "ajax/oferta.html" wygląda następująco:{"tytul":"Oferta","tresc":"Jestesmy wspaniałą firmą z wspaniałą ofertą."}

Kod JS, który załaduje treści:

$(function(){ $("#menu a").click(function(e){ var content=$("#content"); var title=$("#title"); var loader=$("#loader"); $.ajax({ url: "ajax/"+$(this).attr('href'), dataType: "JSON", beforeSend: function(){ content.empty(); title.empty(); loader.show(); }, success: function(obj){ content.html(obj.tresc); title.html(obj.tytul); }, error : function(){ content.html("<p>Przepraszamy, ale strona jest chwilowo niedostępna</p>"); }, complete: function(){ loader.hide(); } }); e.preventDefault(); }) })

Co tu się dzieje? Jak poprzednio przechwytujemy kliknięcie. Potem zapisujemy do zmiennych obiekty jQuery, które reprezentują treść strony, tytuł strony i element informujący o ładowaniu się treści. Dallej wykonanie metody $.ajax() i jak poprzednio wykonujem e.preventDefault();.

Metoda ajax() ma wiele parametrów, które podajemy jako zbiór par klucz:wartosc w nawiasach klamrowych. Użyte w przykładzie wartości to tylko mała część dostępnych, ale do tego zadania wystarczą. Po kolei:

url

Adres pliku, który ma zostać wywołany. W naszym przykładzie, są to pliki html, ale mogły by być pliki PHP, które pobierają dane z bazy danych i po odpowiednim ich sformatowaniu zwracają

dataType

Typ danych, jakich ma oczekiwać metoda. W naszym przykładzie to JSON, ale może być kilka innych np XML,HTML,text.

beforeSend

Kod, który zostanie wykonany przed rozpoczęciem pobierania danych. W naszym przypadku wykorzystujemy funkcje anonimową, w której czyścimy zawartość treści i tytułu strony i za pomocą metody .show() pokazujemy div z informacją o ładowaniu się danych

success

Ta funkcja wykona się jeśli pobieranie danych zakończy się sukcesem. Jako argument przyjmujemy obiekt zwrócony przez wywołany plik (obj). Wewnątrz za pomocą metody html() dodajemy zawartość strony i jej tytuł do naszego szkieletu strony. Dostęp do danych w objekcie obj mamy za pomocą kropek.

error

Funkcja, która wykona się, gdyby z jakiegoś powodu nie udało się pobrać danych np. plik nie istnieje. U nas funkcja wyświetla odpowiedni komunikat.

complete

Ta funkcja wykona się po zakończonym pobieraniu danych, niezależnie od tego czy się powiodło czy nie. Za jej pomocą ukrywamy element strony informujący o pobieraniu danych.

Teraz po kliknięciu w link podczas ładowania strony wyświetli się komunikat ładowaniu danych, dzięki czemu użytkownik nie będzie miał wrażenia, że nic się nie dzieje - zwłaszcza jeśli pobieranie trwa dłużej.

Jeśli stworzycie tak prostą stronę jak ja i będziecie testować to lokalnie, to prawdopodobnie nie zobaczycie komunikatu, albo tylko "błyśnie". To dlatego, że dane są tak pobierane w ułamku sekundy. Sposobem na zobaczenie komunikatu jest użycie php zamiast plików html i na ich początku użycie funkcji sleep(x) gdzie x to ilość sekund, na ile zostanie wstrzymany skrypt.

Po załadowaniu przykładowej strony z ofertą zobaczymy:

Podsumowanie

Na dzisiaj to tyle. Mam nadzieję, że przybliżyłem Wam temat. W następnej części opiszę jak wysyłać dane do serwera i przyjmować odpowiedź. Zrobimy to na przykładzie formularza
kontaktowego.

Link

Link do działającego przykladu: http://przyklady.blog.abryser.pl/jquery1/index.html

HTML w JSON

Ponieważ pojawiły się wątpliwości w komentarzach zaktualizowałem przykład w linku o taki, w którym przez JSON wysyłany jest tekst zawierający HTML i CSS. Po kliknięciu linku "Usługi" wysyłane do przeglądarki jest coś takiego:{"tytul":"Usługi","tresc":"<style type=\"text\/css\">\r\n.jakasKlasa{color:red}\r\n<\/style><p>Nasze usługi - tutaj jest ich opis<br \/>Lista usług:<\/p><ul class=\"jakasKlasa\"><li>Usługa 1<\/li><li>Usługa 2<\/li><li>Usługa 3<\/li><li>Usługa 4<\/li><\/ul>"}Cała rzecz w tym, żeby odpowiednie znaki (ukośniki, cudzysłowy) poprzedzić znakiem backslash.

Część 2

http://www.dobreprogramy.pl/slepciu/AJAX-i-jQuery-cz,31833.html 

programowanie

Komentarze

0 nowych
underface   14 #1 16.04.2012 14:13

na końcu brakuje tylko odnośnika do działającej demówki ;p

underface   14 #2 16.04.2012 14:13

na końcu brakuje tylko odnośnika do działającej demówki ;p

flaszer   10 #3 16.04.2012 14:46

jQuery ma ogromne możliwości. Wszystko fajnie i pięknie, tylko formatowanie końca tekstu jest nieczytelne i chyba nie tak miało wyglądać ;) Podłączam się do sugestii powyżej - czyli link jak to wygląda w praktyce ;)

flaszer   10 #4 16.04.2012 14:47

jQuery ma ogromne możliwości. Wszystko fajnie i pięknie, tylko formatowanie końca tekstu jest nieczytelne i chyba nie tak miało wyglądać ;) Podłączam się do sugestii powyżej - czyli link jak to wygląda w praktyce ;)

hiropter   10 #5 16.04.2012 14:55

Coś się koledze porozjeżdżało na końcu... Proponuję jeszcze raz poddać edycji całość.

  #6 16.04.2012 17:22

Używasz najnowszej wersji jQuery, to dobrze byłoby wiedzieć, że metoda "click" jest już przestarzała i, zdaje się, że od wersji 1.8 wyjdzie całkowicie z użytku, w kodzie bałagan - raz używasz pojedynczych, raz podwójnych cudzysłowów, dalej nie czytałem bo bałagan w formatowaniu

slepciu   11 #7 16.04.2012 19:00

Dzięki za zwrócenie uwagi na rozjechanie się tekstu. Mam wrażenie, że wszystko sprawdzałem przed publikacją, ale było późno w nocy, więc może coś zepsułem. W każdym razie już naprawiłem

Zgodnie z prośba dodałem na końcu link do działającego przykładu

Jim1961   7 #8 16.04.2012 19:27

Duża niekonsekwencja przy średnikach :P

Jim1961   7 #9 16.04.2012 19:27

Duża niekonsekwencja przy średnikach :P

slepciu   11 #10 16.04.2012 19:45

@Jim1961 - późno było jak to pisałem :) W każdym razie postarałem się to trochę usystematyzować

  #11 16.04.2012 20:50

A właśnie dziś czytałem jak budowę tabelaryczną strony zastąpić divami, a tu proszę, dokładny tego przykład :P
Czekam na wpis jak przesyłać zapytania do sql :)

PS. masz a pozostałe id z " " to jakaś różnica?

arlid   14 #12 17.04.2012 08:01

Ciekawy wpis. Szukałem podobnego rozwiązania. Widzę, że masz sporą wiedzę na ten temat. Pozazdrościć, eh gdybym ja tak umiał to bym w końcu stworzył swoja wyśnioną galerie :)

Mam pytanie, co do pliku JSON. Czy można tam stosować HTM? A co ze stylami, da się zastosować oddzielny arkusz, czy wystarczy wszystko umieścić w tym "głównym" i treść z pliku JSON zostanie ostylowana z arkusza "głównego" (oczywiście, jeżeli tam zastosujemy klasy jak w pliku arkusza)? Wiem, że może trochę zagmatwałem, ale mam nadzieję, że wiadomo o co chodzi.

alucosoftware   7 #13 17.04.2012 09:23

@arlid

JSON to tylko notacja (czyt. struktura/format/sposób zapisu). Nic nie stoi na przeszkodzie aby np. "obj.tresc" zawierała znaczniki html lub klasy css. Tak czy siak slepciu wykorzystuje później metodę .html(), która "oczekuje lub nie" znaczników HTML'a.

alucosoftware   7 #14 17.04.2012 09:24

@slepciu

Fajny wpis

  #15 17.04.2012 09:27

Kod przesłany ajax będzie miał właśnie styl przyporządkowany danym identyfikatorom ze strony na którą treść zostanie wklejona.

slepciu   11 #16 17.04.2012 11:19

@cerro - fajnie, że wpis się przydał nawet poza głównym tematem. Jeśli chodzi o apostrofy i cudzysłowy, to w HTML'u to nie ma znaczenia, chociaż warto być konsekwentnym - ładniej to wygląda i wyrabia dobre nawyki - ja mam problem z tą konsekwencją

@arlid - tak jak napisał alucosoftware za pomocą JSON można przesyłać praktycznie wszytko. W PHP są funkcje, które ułatwiają kodowanie i dekodowanie JSON: json_encode() i json_decode()

@alucosoftware - dzięki

alucosoftware   7 #17 17.04.2012 14:18

@slepciu

Jeśli planujesz kolejne wpisy, może pokażesz innym jak w jQuery wybierać elementy wykorzystując wiele selektorów naraz. Dzięki takiemu podejściu nie będziesz musiał każdemu elementowi przyporządkowywać osobnej nazwy/id/class itd.

Często wiele elementów dziedziczy styl po danej klasie css, a my potrzebujemy zmienić tylko jeden wybrany element w drzewie powiązanych obiektów.

arlid   14 #18 17.04.2012 18:20

To ja coś robię nie tak. Po edytowaniu pliku JSON wstawiam w "" po treść kod HTML i nic mi się nie wyświetla :P Pusto jest ;) Ale walcze nadal.

alucosoftware   7 #19 17.04.2012 18:46

@arlid

Może też używasz nawiasów w swoim kodzie... np. "". Powinno być wtedy "" lub inne łączenie łańcuchów znaków...

alucosoftware   7 #20 17.04.2012 18:48

@arlid

ech... zjadło znaczniki...

[code=html]
""
""
[/code]

alucosoftware   7 #21 17.04.2012 18:49

@arlid

:) Poddaję się. Wykorzystaj cudzysłów pojedynczy ' ' zamiast " "

djfoxer   18 #22 17.04.2012 22:27

@arlid
Zdebuguj (w większości przeglądarek F12), sobacz co jest wysyłane i co zwracane, może jakieś błędy podczas wysyłania są, czy coś. W chromie jest ciekawa zakładka "Network", w FF po doinstalowaniu Firebuga zakładka "Sieć".

slepciu   11 #23 17.04.2012 22:56

@arlid - zaktualizowałem przykład o taki, w którym wysyłany jest HTML i CSS, na końcu dodałem na ten temat notkę. To powinno pomóc.

slepciu   11 #24 17.04.2012 23:00

@alucosoftware - planuję na razie co najmniej jeden wpis, ale może pójdę za, Twoją radą i coś jeszcze napiszę na temat selektorów, tylko nie jestem pewny o czym mówisz. Czy chodzi Ci o poruszanie się po DOM za pomocą .next(),.eq(), .prev() itp.

djfoxer   18 #25 18.04.2012 07:53

@slepciu
http://api.jquery.com/category/selectors/
W sumie selektory w jq są niesamowite, robienie teraz w czystym js byłoby może nie niemożliwe, ale dużo bardziej pracochłonne i podatne na błędy niż w jq. Może jakiś przegląd mało znanych i oryginalnych wtyczek do jq?

alucosoftware   7 #26 18.04.2012 09:59

Właśnie o to mi chodziło. Sam często wykorzystuję wielokrotne selektory klas css.

Tak przy okazji, jak w komentarzach umieszczać znaczniki html? :)

slepciu   11 #27 18.04.2012 10:25

@djfoxer - ja tez nie wyobrażam sobie teraz pisania w czystym JS, jQuery upraszcza życie. Jakiś przegląd wtyczek planuję, ale czy będą mało znane to nie wiem, będą takie, z których ja często korzystam

@alucosoftware - w takim razie postaram się coś napisać w przyszłości o tych selektorach :) Co do znaczników HTML w komentarzach - to nie mam pojęcia.

alucosoftware   7 #28 18.04.2012 12:11

@djfoxer

W nawiązaniu do wtyczek, widziałeś SharpKit? Czego to ludzie nie wymyślą ;)

djfoxer   18 #29 18.04.2012 17:26

@alucosoftware
Pierwsze widzę :) Wygląda to trochę dziwacznie i pewnie nie pokrywa w 100% jq, a już o js nie wspominając. Ehhh, faktycznie ludzka wyobraźnie nie zna granic :D

tfl   8 #30 18.04.2012 21:44

Dobrym zwyczajem jest wykonanie metody preventDefault, gdy ingeruje sie w event click na anchorach. zwracanie false jest... jakos tak... malo koszerne.

slepciu   11 #31 18.04.2012 22:14

@tfl - masz rację, stare głupie nawyki jeszcze nieraz późną porą wychodzą. Już poprawiłem w tekście i przykładzie. Z tym "malo koszerne" to jest niezłe określenie :)

alucosoftware   7 #32 18.04.2012 22:52

Hmm, a czy przypadkiem nie jest to (return false) jednoznaczne z preventDefault + stopPropagation?

slepciu   11 #33 18.04.2012 23:08

@alucosoftware - masz rację

tfl   8 #34 19.04.2012 07:36

@alucosoftware

No jest. A nawet wiecej, bo jeszcze do tego dojdzie zatrzymanie wykonywania metody. Ale co z tego? stopPropagation sluzy do jednego, preventdefault do drugiego. W tym przypadku nie widze zestosowania dla stopPropagation w ogole. Koszernie trzeba pisac:)

slepciu   11 #35 19.04.2012 11:05

W tym przypadku użycie obu sposobów daje taki sam rezultat, ale rzeczywiście w niektórych przypadkach false mogłoby nam zepsuć trochę działanie skryptu. Dla ciekawych tutaj można przeczytać krótki artykuł na ten temat: http://css-tricks.com/return-false-and-prevent-default/

arlid   14 #36 19.04.2012 11:33

@slepciu
Dzięki. Już wiem, gdzie zrobiłem błąd :) No teraz to magia. Czekam na wpis o wysyłaniu danych i przyjmowaniu odpowiedzi o jakim piszesz w podsumowaniu. Jak widzę, chyba muszę troszkę bardziej się w to zagłębić bo to bardzo ciekawe jest :)

slepciu   11 #37 19.04.2012 12:12

@arlid - No to fajnie. Jak Ci się podoba to polecam ogólnie poczytać o jQuery, bo naprawdę spore możliwości. Natomiast, żeby w pełni wykorzystać AJAX przydaje się znajomość jakiegoś języka działającego po stronie serwera, ja w kolejnym przykładnie będę wykorzystywał PHP

  #38 21.01.2014 08:57

Witam,
mam problem, bo nie wyświetlają mi się strony po kliknięciu w link.
Komunikat "Przepraszamy, ale strona jest chwilowo niedostępna".
Kod dokladnie przepisany i cos nie tak ;/. W czym moze byc problem?

slepciu   11 #39 21.01.2014 23:54

@suip (niezalogowany) - użyj Firefoxa, zainstaluj dodatek Firebug i włącz go. Spróbuj uruchomić stronę i zobacz co się pojawia w zakładce Konsola Firebuga. Jak będziesz miał problem wklej treść jak atam będzie w odpowiedzi po kliknięciu przycisku. Sprawdź też dokładnie czy w pliku oferta.html jest dokładnie to co powinno być i nic więcej. Możesz tez pobrać działający przykład i porównać zawartość plików