1/13
gajdaw.pl/ajax/ajax-php-wymiana-fragmentu-strony/print.html
Ajax. Kurs od podstaw. Część 4: Wymiana fragmentu
strony
Włodzimierz Gajda
Wymiana fragmentu strony WWW bez przeładowania całego dokumentu wiąże się z kilkoma problemami. Stosując takie
rozwiązania należy sprawdzić m.in. czy witryna jest dostępna dla robotów jak się zachowuje przy wyłączonej interpretacji
JavaScript oraz jak stosowane rozwiązanie wpływa na transfer. Artykuł opisuje sześć przykładowych implementacji wymiany
fragmentu oraz przedstawia szczegółową analizę cech proponowanych rozwiązań.
Spis treści
1. Asynchroniczna wymiana fragmentu witryny
1.1 Przykład
1.2 Dane w formacie HTML
2. Rozwiązanie pierwsze: Ajax
2.1 Cechy rozwiązania
3. Rozwiązanie drugie: Ajax i hiperłącza
3.1 Cechy rozwiązania
4. Rozwiązanie trzecie: tablica danych JavaScript
4.1 Cechy rozwiązania
5. Rozwiązanie czwarte: tablica JavaScript i hiperłącza
5.1 Cechy
6. Rozwiązanie piąte: zmiana widoczności warstw
6.1 Cechy rozwiązania
7. Rozwiązanie szóste: warstwy i hiperłącza
7.1 Cechy
8. Podsumowanie
1. Asynchroniczna wymiana fragmentu witryny
Wymiana fragmentu witryny bez przeładowywania całej strony jest popularnym rozwiązaniem, które znajdziemy między
innymi w serwisach
http://www.yahoo.com
oraz
http://www.fotozakupy.pl
.
2/13
gajdaw.pl/ajax/ajax-php-wymiana-fragmentu-strony/print.html
Menu zaznaczone czerwoną obwódką na rysunkach 1 oraz 2 powoduje wymianę treści fragmentu zaznaczonego zieloną
obwódką.
Rysunek 1. Wymiana fragmentu witryny Yahoo.com
Rysunek 2. Wymiana fragmentu witryny Fotozakupy.pl
Rozwiązanie zawarte w serwisie Yahoo wykorzystuje Ajax i działa także przy wyłączonym JavaScript-cie (oczywiście strona
jest wówczas przeładowywana w całości). Natomiast serwis Fotozakupy stosuje zmianę widoczności warstw bez użycia
Ajax-a (komplet tekstów jest zawarty w głównym dokumencie HTML). Rozwiązanie takie nie działa, gdy wyłączymy
JavaScript.
1.1 Przykład
Omawiane zagadnienie przedstawię od strony praktycznej wykorzystując przykład widoczny na rysunku 3. Menu strony jest
3/13
gajdaw.pl/ajax/ajax-php-wymiana-fragmentu-strony/print.html
zaznaczone czerwoną obwódką. Po aktywacji jednej z opcji menu odpowiednia treść jest ładowana do pojemnika oznaczonego
zieloną obwódką.
Rysunek 3. Przykładowa strona prezentująca wymianę fragmentu witryny
Kod HTML przykładu ma postać:
<div id="pojemnik">
<ol id="menu">
<li>...</li>
<li>...</li>
...
</ol>
<div id="content"></div>
</div>
1.2 Dane w formacie HTML
Przykład prezentuje zawartość pięciu płyt muzycznych.
ABBA: Super Trouper
AC/DC: Flick of the Switch
Aerosmith: Draw the Line
Black Sabbath: Eternal Idol
Bob Dylan: Basement Tapes
Pliki:
fragment-abba.html
fragment-ac_dc.html
fragment-aerosmith.html
fragment-black_sabbath.html
4/13
gajdaw.pl/ajax/ajax-php-wymiana-fragmentu-strony/print.html
fragment-bob_dylan.html
zawierają kod HTML. Nie są to kompletne strony WWW, a jedynie fragmenty, które należy umieścić w pojemniku
div#content
przeznaczonym na treść.
Oto zarys pliku
fragment-bob_dylan.html
:
<h1>Bob Dylan</h1>
<h2>Basement Tapes</h2>
<h2>1975</h2>
<table>
<tr>
<th>lp.</th>
<th>title</th>
<th>czas</th>
</tr>
<tr>
<td>1.</td>
<td>Odds and Ends</td>
<td>1:46</td>
</tr>
<tr>
<td>2.</td>
<td>Orange Juice Blues (Blues for Breakfast)</td>
<td>3:37</td>
</tr>
...
</table>
Każdy plik z opisem płyty zawiera element
h1
(nazwa zespołu), dwa elementy
h2
(tytuł płyty oraz rok wydania) oraz tabelę z
listą utworów.
Po wstawieniu pliku
fragment-bob_dylan.html
do strony przedstawionej na rysunku 3 otrzymamy kod:
<div id="pojemnik">
<ol id="menu">
...
</ol>
<div id="content">
<h1>Bob Dylan</h1>
<h2>Basement Tapes</h2>
<h2>1975</h2>
<table>
...
</table>
</div>
</div>
2. Rozwiązanie pierwsze: Ajax
Przeprowadzenie wymiany fragmentu strony WWW przy użyciu Ajax-a wymaga ustalenia dla każdej opcji menu dwóch
parametrów:
adresu URL dokumentu, który będzie załadowany,
identyfikatora
id
elementu XHTML, w którym należy umieścić pobraną treść.
5/13
gajdaw.pl/ajax/ajax-php-wymiana-fragmentu-strony/print.html
Ładowanymi dokumentami są pliki:
fragment-abba.html
fragment-ac_dc.html
...
Każde hiperłącze ładuje treść do tego samego elementu: pojemnika
div
o identyfikatorze
content
.
Wymianę treści realizuje funkcja
wymienTresc()
. Ma ona dwa parametry: adres
url
oraz identyfikator
id
:
wymienTresc(url, id)
Hiperłącza zawarte w menu przyjmą postać:
<a href="#"
onclick="wymienTresc('fragment-abba.html', 'content');">
ABBA: Super Trouper
</a>
<a href="#"
onclick="wymienTresc('fragment-bob_dylan.html', 'content');">
Bob Dylan: Basement Tapes
</a>
Funkcja
wymienTresc()
pochodzi z pliku
ajax.js
. Jest ona zaimplementowana przy użyciu obiektu
XMLHttpRequest
:
var r;
var e;
function odbierzDane()
{
if (r.readyState == 4) {
if (r.status == 200 || r.status == 304) {
e.innerHTML = r.responseText;
}
}
}
function wymienTresc(adresurl, htmlid)
{
if (r = getXMLHttpRequest()) {
e = document.getElementById(htmlid);
r.open('GET', adresurl);
r.onreadystatechange = odbierzDane;
r.send(null);
}
}
Rozwiązanie takie działa tylko wtedy, gdy w przeglądarce włączona jest obsługa JavaScript. Wykorzystując okno dialogowe
Narzędzia → Opcje → Treść
wyłącz obsługę języka JavaScript. Przykład przestanie działać. (Wyłączanie JavaScript w
przeglądarce Internet Explorer 6 jest przedstawione na rysunku 5).
6/13
gajdaw.pl/ajax/ajax-php-wymiana-fragmentu-strony/print.html
Rysunek 4. Wyłączanie JavaScript w przeglądarce Firefox
Rysunek 5. Wyłączanie JavaScript w przeglądarce Internet Explorer 6
2.1 Cechy rozwiązania
Główną wadą podanego rozwiązania jest to, że nie działa ono przy wyłączonym JavaScript-cie. Treść podstron jest
niedostępna dla robotów wyszukiwarek.
Ponadto strona taka wymaga korzystania z serwera HTTP. Pomimo, że są to statyczne pliki HTML, przykład nie będzie działał
offline czyli np. po nagraniu na płycie CD.
Kolejnym minusem jest to, że ładowanie podstron z sieci będzie powodowało mrugnięcie lub chwilowe zatrzymanie aplikacji.
7/13
gajdaw.pl/ajax/ajax-php-wymiana-fragmentu-strony/print.html
Cały przykład jest widoczny w sieci pod jednym adresem URL:
index.html
. Należy pilnować, by adresy
fragment-
xxx.html
nie stały się dostępne publicznie, gdyż w przeciwnym razie grozi nam ten sam problem, co w przypadku ramek
HTML. Użytkownicy mogą trafić na dziwne fragmentaryczne strony, nie mając żadnego odsyłacza prowadzącego do
dokumentu macierzystego.
Takie podejście minimalizuje transfer danych: za każdym razem z serwera pobierane są tylko konieczne informacje.
Fragmenty, które się nie zmieniają (np. menu) nie są pobierane przy każdym żądaniu HTTP.
3. Rozwiązanie drugie: Ajax i hiperłącza
W jaki sposób zapewnić, by witryna działała po wyłączeniu JavaScript? Najpierw przygotowujemy tradycyjna witrynę, która
w menu posiada zwykłe hiperłącza. Należy przygotować pięć plików:
abba.html
,
ac_dc.html
,
aerosmith.html
,
black_sabbath.html
,
oraz
bob_dylan.html
.
Każda z tych stron zawiera identyczne menu oraz opis jednej z płyt. Hiperłącza menu są tradycyjnymi hiperłączami, które
dodatkowo posiadają obsługę zdarzenia
onclick
:
<a href="abba.html"
onclick="wymienTresc('fragment-abba.html', 'content', this);">
ABBA: Super Trouper
</a>
Przy wyłączonej interpretacji kodu JavaScript hiperłącze będzie działało w tradycyjny sposób.
Jeśli natomiast obsługa JavaScript jest włączona, wówczas zostanie dodatkowo wywołana funkcja
wymienTresc()
. Należy
w niej wykonać kod, który wyłączy przeładowanie strony.
Przeładowanie strony możemy wyłączyć zmieniając adres
href
hiperłącza na
#
. W tym celu funkcja
wymienTresc()
otrzymała trzeci parametr:
this
. Jest to obiekt DOM — kliknięte hiperłącze menu. Przeładowanie dokumentu wyłączamy
ustalając wartość atrybutu
href
klikniętego hiperłącza:
function wymienTresc(adresurl, htmlid, hiperlacze)
{
if (r = getXMLHttpRequest()) {
e = document.getElementById(htmlid);
r.open('GET', adresurl);
r.onreadystatechange = odbierzDane;
r.send(null);
hiperlacze.href = '#';
}
}
3.1 Cechy rozwiązania
8/13
gajdaw.pl/ajax/ajax-php-wymiana-fragmentu-strony/print.html
Drugi przykład działa poprawnie bez względu na to, czy obsługa JavaScript jest włączona czy wyłączona. Odbywa się to
kosztem tego, że witryna składa się teraz z dziesięciu plików. Pięć z nich zawiera tradycyjne kompletne strony WWW.
Pozostałe pięć — fragmenty, które należy umieścić wewnątrz pojemnika
div#content
. Można powiedzieć, że każda
podstrona jest wykonywana dwukrotnie: raz jako pełna strona WWW (np.
abba.html
) wykorzystywana przy wyłączonym
JavaScript, drugi raz jako fragment (np.
fragment-abba.html
) użyty przez Ajax-a.
Tak wykonany przykład wymaga serwera HTTP. Wersja offline witryny będzie działała wyłącznie po wyłączeniu obsługi
JavaScript.
Podobnie jak poprzednio ładowanie podstron przez Ajax-a powoduje chwilowy przestój.
4. Rozwiązanie trzecie: tablica danych JavaScript
W celu eliminacji mrugnięcia powodowanego pobieraniem danych przez Ajax oraz udostępnienia działającej witryny offline
należy zrezygnować z Ajax-a i umieścić komplet danych wewnątrz pobieranej witryny. Można do tego wykorzystać tablice
JavaScript.
Cała witryna składa się tym razem z dwóch plików:
index.html
oraz
tab.js
. Plik
index.html
zawiera menu oraz
pojemnik
div#content
, zaś
tab.js
— treść wszystkich podstron oraz skrypt przeładowujący zawartość pojemnika
div#content
.
Hiperłącza menu mają postać:
<a href="#"
onclick="wymienTresc('1', 'content');">
ABBA: Super Trouper
</a>
Funkcja
wymienTresc()
pobiera zamiast adresu URL identyfikator podstrony.
W pliku
tab.js
znajduje się tablica
dane
oraz funkcja
wymienTresc()
. Tablica
dane
zawiera kompletną treść wszystkich
podstron (tj. zawartość pięciu plików
fragment-abba.html
,
fragment-ac_dc.html
, itd.):
var dane = new Array;
dane[1] = '<h1>ABBA</h1>...<table>...</table>';
dane[2] = '<h1>AC/DC</h1>...<table>...</table>';
dane[3] = '<h1>Aerosmith</h1>...<table>...</table>';
...
Wymiana treści sprowadza się do jednej instrukcji przypisania:
function wymienTresc(id, htmlid)
{
document.getElementById(htmlid).innerHTML = dane[id];
}
4.1 Cechy rozwiązania
9/13
gajdaw.pl/ajax/ajax-php-wymiana-fragmentu-strony/print.html
Przykład ten oczywiście nie działa po wyłączeniu JavaScript. Nie wymaga on stosowania serwera HTTP i będzie działał w
wersji offline ale tylko przy włączonym JavaScript-cie.
Z racji na to, że komplet danych jest zawarty w dwóch plikach i po kliknięciu opcji menu nie są wysyłane żadne żądania
HTTP, w przykładzie nie występują żadne przestoje ani mrugnięcia.
Ocena wpływu rozwiązania na transfer zależy od rodzaju wizyty. Jeśli ktoś wejdzie na jedną tylko podstronę to transfer będzie
większy niż przy tradycyjnie wykonanej stronie z jednym menu, gdyż pobrana zostanie treść wszystkich pozycji menu. Jeśli
natomiast podczas wizyty użytkownik odwiedzi wiele różnych pozycji menu, to transfer będzie niższy niż przy rozwiązaniu
tradycyjnym. Wynika to stąd, że skrypt
tab.js
jest zapisywany przez przeglądarkę w pamięci podręcznej i będzie pobrany
tylko raz.
5. Rozwiązanie czwarte: tablica JavaScript i hiperłącza
Rozwiązanie stosujące tablicę JavaScript możemy wzbogacić o obsługę tradycyjnych hiperłączy. Rozwiązanie składa się
wówczas z pięciu statycznych plików HTML:
abba.html
,
ac_dc.html
, itd. oraz pliku
tab.js
.
Hiperłącza menu mają postać:
<a href="abba.html"
onclick="wymienTresc('1', 'content', this);">
ABBA: Super Trouper
</a>
5.1 Cechy
Przykład ten działa w wersji offline i nie wymaga JavaScript. Komplet danych stosowanych do przeładowania zawartości jest
zawarty w pliku
tab.js
. Zatem w przykładzie uruchomionym z obsługą JavaScript nie zauważymy przestoju związanego z
pobieraniem danych z serwera.
6. Rozwiązanie piąte: zmiana widoczności warstw
Ostatnim rozwiązaniem jest umieszczenie kompletu danych wewnątrz kodu HTML:
<div id="content">
<div id="opcja1">
<h1>ABBA</h1>
...
<table>
...
</table>
</div>
<div id="opcja2">
<h1>AC/DC</h1>
...
<table>
...
</table>
</div>
...
</div>
10/13
gajdaw.pl/ajax/ajax-php-wymiana-fragmentu-strony/print.html
Obsługa aktywacji opcji menu sprowadzi się wówczas do przełączenia widoczności warstw.
Hiperłącza menu wymagają jedynie jednego parametru:
<a href="#"
onclick="wymienTresc('opcja1');">
ABBA: Super Trouper
</a>
Funkcja
wymienTresc()
wyłącza widoczność wszystkich opcji, po czym ponownie włącza widoczność opcji przekazanej
jako parametr:
function wymienTresc(id)
{
ukryj();
document.getElementById(id).style.display = 'block';
}
Natomiast funkcja
ukryj()
wyłącza widoczność wszystkich opcji:
function ukryj()
{
document.getElementById('opcja1').style.display = 'none';
document.getElementById('opcja2').style.display = 'none';
...
}
6.1 Cechy rozwiązania
Rozwiązanie to działa wyłącznie przy włączonym JavaScript. Będzie ono poprawne także w wersji offline.
Wprawdzie cała treść zawarta w dokumencie jest dostępna dla robotów, jednak wiąże się z tym pewien kłopot. Wyszukiwarka
może zwrócić wyniki wyszukiwania, które wprawdzie zawierają żądane frazy, jednak frazy te nie są widoczne.
Pod względem transferu rozwiązanie takie będzie niekorzystne. Każda wizyta na dowolnej podstronie będzie powodowała
pobieranie kompletu danych.
7. Rozwiązanie szóste: warstwy i hiperłącza
W rozwiązaniu stosującym tradycyjne hiperłącza wraz ze zmianą widoczności warstw hiperłącza menu przyjmą postać:
<a href="abba.html"
onclick="wymienTresc('opcja1', this);">
ABBA: Super Trouper
</a>
Wewnątrz funkcji
wymienTresc()
należy zmienić widoczność warstw oraz zmieniając adres
href
klikniętego hiperłącza
wyłączyć przeładowanie witryny.
7.1 Cechy
11/13
gajdaw.pl/ajax/ajax-php-wymiana-fragmentu-strony/print.html
Oczywiście rozwiązanie to działa przy wyłączonym JavaScript. Może ono być stosowane offline.
8. Podsumowanie
W charakterystyce podanych rozwiązań należy uwzględniać odpowiedzi na następujące pytania:
Czy rozwiązanie działa bez JavaScript?
Czy rozwiązanie działa w trybie offline (bez serwera HTTP, np. z płyty CD)?
Czy występuje chwilowa przerwa (mrugnięcie) spowodowana transferem danych z serwera?
Czy treść podstron jest dostępna dla robotów, które nie interpretują JavaScript?
Czy wyszukiwarka ma szanse zwrócić dobre wyniki wyszukiwania?
Czy stronę można dodać do zakładek?
Jaka jest liczba przygotowywanych podstron oraz stosowanych adresów URL?
Czy występują adresy fragmentaryczne, które należy ukrywać?
Jak rozwiązanie wpływa na transfer danych?
Dostępność dla robotów jest tożsama z działaniem przy wyłączonym JavaScript, zaś kwestie transferu należy osobno
rozpatrywać dla stron przy włączonym, a osobno przy wyłączonym JS.
Tabela 1 zawiera pełną charakterystykę omówionych przykładów. Podany transfer należy traktować orientacyjnie. Duże
znaczenie będzie miała liczba opcji menu, rozmiar kodu HTML każdej opcji jak również to, które podstrony i ile razy zostaną
pobrane.
Przykład
Bez
JavaScript
Offfline
Mrugnięcie
Dostępność
dla
robotów
Dobre wyniki
wyszukiwania
Podstrony,
adresy
URL
Adresy
fragmentów
Transfer
JS
Transfer
bes JS
Pierwszy:
Ajax
nie działa
nie działa
występuje
niedostępna nie
n + 1
(indeks +
fragmenty)
tak
minimalny -
Drugi:
Ajax i
hiperłącza
działa
działa przy
wyłączonym
JS
występuje
dostępna
tak
2 * n
(pełny
dokument
+
fragment)
tak
minimalny tradycyjny
Trzeci:
tablica
nie działa
działa przy
włączonym
JS
nie
występuje
niedostępna nie
1
nie
gorszy od
tradycyjnej
witryny
-
Czwarty:
tablica i
działa
działa
nie
gorszy od
12/13
gajdaw.pl/ajax/ajax-php-wymiana-fragmentu-strony/print.html
hiperłącza
występuje
dostępna
tak
n
nie
tradycyjnej
witryny
tradycyjny
Piąty:
warstwy
nie działa
działa przy
włączonym
JS
nie
występuje
dostępna
nie
1
nie
znacznie
gorszy od
tradycyjnej
witryny
-
Szósty:
warstwy
i
hiperłącza
działa
działa
nie
występuje
dostępna
tak
n
nie
znacznie
gorszy od
tradycyjnej
witryny
maksymalny
Tabela 1. Charakterystyka opisanych przykładów
W zależności, czy przygotowywany dokument będzie publikowany w sieci czy umieszczany na płycie CD otrzymamy
zupełnie inne wymagania.
Odnośnie dokumentów publikowanych w internecie najlepszym wydaje mi się rozwiązanie drugie: tradycyjne hiperłącza
wzbogacone o przeładowanie fragmentu wykorzystujące Ajax. Witryna działa przy wyłączonym JavaScript, jest dostępna dla
robotów, a transfer zostaje zminimalizowany. Niestety, dodawanie podstron do zakładek przeglądarki nie będzie działało
poprawnie.
W przypadku stron nagrywanych na CD rozwiązaniami równorzędnymi są czwarte oraz szóste.
lp.
Przykład
1.
Przykład pierwszy: Ajax
2.
Przykład drugi: Ajax i hiperłącza
3.
Przykład trzeci: tablica JavaScript
4.
Przykład czwarty: tablica JavaScript i hiperłącza
5.
Przykład piąty: warstwy
6.
Przykład szósty: warstwy i hiperłącza
7.
Dane
Tabela 2. Przykłady do pobrania
13/13
gajdaw.pl/ajax/ajax-php-wymiana-fragmentu-strony/print.html
Reklama