3/2007
Narzędzia
54
JavaScript
www.phpsolmag.org
55
W
raz z rozwojem technologii interne-
towych, doczekaliśmy się tak roz-
budowanych narzędzi, że w dzi-
siejszych czasach tworzenie aplikacji interneto-
wych z interfejsem podobnym do interfejsów
systemów operacyjnych nie stanowi najmniej-
szego problemu. Przyjrzyjmy się kilku najpopu-
larniejszym i najciekawszym, moim zdaniem,
zestawom skryptów oraz frameworkom uła-
twiającym nam pracę z JavaScript.
Dojo
Dojo Toolkit jest potężnym narzędziem, skrypt
wraz ze wszystkimi bibliotekami zajmuje 5MB,
jednak znajdziemy w nim dosłownie wszystko, od
prostych bibliotek pozwalających na rozjaśnienia,
płynne przesunięcia czy zmianę rozmiaru, do za-
awansowanych, wspomnianych we wstępnie, dra-
g&drop
'ów, drzewek czy edytora WYSIWYG. Za-
wiera on całą gamę elementów pozwalających na
budowę interfejsu aplikacji: zakładki, okienka, ta-
kie same jak te znane nam z Microsoft Windows.
Elementy te zawierają się jednak w większości
omawianych dzisiaj frameworków. Czym więc
wyróżnia się Dojo? Dojo Toolkit wyróżnia się mo-
dułem zwanym dojo.storage. Przeglądarki interne-
towe pozawalają witrynom przechowywać dane
po stronie użytkownika, różnego rodzaju infor-
macje można przechowywać w cookies (do 4KB),
w cache Flash Playera (do 100KB), userData Inter-
net Explorera (z limitem do 1MB), DOM Stora-
ge (do 5MB) w MozilliFireFox. Programiści wpa-
dli, więc na pomysł, aby wykorzystać te miejsca,
do przechowywania danych, na których operuje
użytkownik. Pozwala to na utworzenie aplikacji,
która daje możliwość pracy w trybie offline, cał-
kowicie bez dostępu do Internetu, w której syn-
chronizacja danych odbywa się dopiero po uzy-
skaniu połączenia. Na stronie domowej Dojo w
dziale Demos znajduje się właśnie aplikacja, któ-
ra demonstruje działanie tej biblioteki. Na pew-
no warto na nią zwrócić uwagę tworząc wszel-
kiego rodzaju systemy zarządzania treścią. Spró-
bujmy w Dojo wykonać element drag&drop, czy-
li coś, co umożliwi nam przenoszenie z jednego
do drugiego elementu jakichś przedmiotów, sy-
mulację naszego sklepu z koszykiem. Pobieramy
dojo i do utworzonego przez nas folderu kopiu-
jemy pliki dojo.js, iframe_history.htm oraz cały fol-
der src – znajdują się w nim wszystkie biblioteki,
które możemy załadować poprzez skrypt. Stwórz-
my teraz przykładowy skrypt - jego treść zobaczyć
można na pierwszym Listingu. (Wszystkie skryp-
ty zamieszczone są również na płycie CD dołączo-
nej do czasopisma). W treści strony deklarujemy
3 sekcje div. Jedną odpowiadającą za listę produk-
tów, następną za koszyk oraz kolejną w celach te-
stowych i aby, wyświetlała nam, jakie informacje
należałoby np. zapisać w bazie danych, czyli status
koszyka. Dojo posiada funkcję odpowiedzialną za
ładowanie części swoich bibliotek, aby niepotrzeb-
nie nie ładować całości, co zajmowałoby dość dużo
pamięci i niepotrzebnie obciążałoby przeglądarkę.
My potrzebujemy jedynie obiektu event oraz dnd.
Za pośrednictwem pierwszego z nich obsługuje-
my wydarzenia, czyli ładujemy skrypt po załado-
waniu strony oraz wywołujemy funkcję update.
Drugi dostarcza nam funkcji odpowiedzialnych
za znany z systemów operacyjnych drag&drop.
Aby skrypt zadziałał poprawnie należy zdefinio-
wać obiekty, które można upuszczać oraz obiekty,
które można przenosić. Dojo pozwala na zdefinio-
wanie kilku rodzajów elementów podnoszonych
oraz elementów, które można upuszczać w odpo-
wiednie miejsca. Uzyskujemy w ten sposób duże
pole działania. Dojo, jako jedyny z opisywanych
frameworków pozwala na asynchroniczny upload
plików, czy też obsługę Ajaxowego wstecz. Jako
minusy Dojo uznać musimy jego rozmiar oraz do-
kumentację średniej jakości. Trzeba się dobrze na-
gimnastykować, aby coś w niej odnaleźć. Plusy to
z pewnością zakres bibliotek, jakie dostarcza oraz
wspomniany dojo.storage.
Prototype
Prototype jest jedynie frameworkiem, który
możemy wykorzystać podczas budowy naszych
bibliotek. Dostarcza on również wygodnego in-
terfejsu do obsługi zapytań Ajaxowych i wyda-
rzeń (eventów). Na Listingu 3. zaprezentowa-
ny został przykład użycia tego interfejsu. Jako
pierwszy parametr funkcji observe podajemy
id elementu, do którego się odnosi, jako drugi
akcję, po której ma zostać uruchomiona funk-
cja z parametru trzeciego. Podstawowym i bar-
dzo częstym błędem popełnianym przez pro-
gramistów jest odwoływanie się do niezałado-
wanych elementów DOM. Dodanie eventu ob-
serve
do myForm może nastąpić dopiero po je-
go załadowaniu (wczytaniu przez przeglądar-
kę całego kodu html). Można temu zaradzić na
dwa sposoby. Pierwszy, mało elegancki, to usta-
wienie eventu w treści strony, dopiero po zała-
dowaniu formularza. Drugi sposób polega na
pewnego rodzaju wstawieniu eventa w event.
Listing 4. opisuje właśnie taki przykład. W mo-
mencie załadowania obiektu window, czyli po
wczytaniu strony, ustawiane są elementy odpo-
wiedzialne za całą resztę zdarzeń – w tym przy-
padku obsługę formularza. Prototype dostarcza
JavaScript
Sklep internetowy, na którym chwytamy produkt niczym folder w
popularnym systemach operacyjnych i przesuwamy do koszyka, jakiś
czas temu znajdował się jeszcze w sferze naszych marzeń. Rozwój
technologii zdecydowanie ułatwił nam życie.
Co obiecujemy...
l
Nazuczysz się tworzyć skrypty z wykorzysta-
niem funkcji drag&drop w Dojo.
l
Dowiesz się jakie daje możliwości biblioteka
Scribus.aculo.us.
Co należy wiedzieć...
l
Powinieneś znać podstawy JavaScript
l
Powinieneś umieć korzystać z gotowych roz-
wiązań typu Dojo
Poziom trudności
Biblioteki i frameworki
3/2007
Narzędzia
54
JavaScript
www.phpsolmag.org
55
Listing 1. Przykładowy skrypt drag&drop wykonany w dojo
<
!DOCTYPE HTML PUBLIC
"-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd"
>
<
html xmlns
=
"http://www.w3.org/1999/xhtml"
xml:lang
=
"pl"
lang
=
"pl">
<
head
>
<
title
>
Dojo drag
&
amp
;
drop test
</
title
>
<
script type
=
"text
/
javascript
" src="
dojo.js
"></script>
<
script type
=
"text
/
javascript
">
// ładowanie bibliotek
// obiekt pozwalający nam obsłużyć eventy
dojo.require(
"dojo.event.*"
)
;
// drag & drop
dojo.require(
"dojo.dnd.*"
)
;
// w dojo przyjęło się używać tego aliasu funkcji
function byId(id)
{
return
document.getElementById(id)
;
}
function init()
{
// pobranie diva z produktami
var
products
=
dojo.byId(
"products"
)
;
// przygotowanie tablicy na obiekty dojo,
// zawierające dane o produktach
var
product
=
new
Array()
;
// pobranie diva z zamowieniami
var
shoppingcart
=
dojo.byId(
"shoppingcart"
)
;
/* ustalamy miejsca gdzie można upuszczać elementy,
jako drugi parametr podaje się typy elementow,
jakie można upuscic */
new
dojo.dnd.HtmlDropTarget(products,
[
"products"
])
;
new
dojo.dnd.HtmlDropTarget(shoppingcart,
[
"products"
])
;
// pobieramy wszystkie elementy - produkty
var
lis
=
products.getElementsByTagName(
"div"
)
;
for
(
var
x
=
0
;
x
<
lis.length
;
x++)
{
// ustalenie źródeł - elementów które można
// podnieść, i ich typów
product[x]
=
new
dojo.dnd.HtmlDragSource(
lis[x],
"products"
)
;
// dodanie wydażenia, po upuszczeniu elementu
// wywołuje funkcję update
dojo.event.connect(product[x],
"onDragEnd"
,
"update"
)
;
}
}
/* Funkcja, która mówi nam ze cos sie stało. Docelowo
można nią obsłużyć zapis w bazie dotyczący zamówień
itp. */
function update(e)
{
byId(
'debug'
).innerHTML +
=
"Wykonanie operacji na
bazie danych dotyczącej id:"
+ e.dragObject.domNode.id+
"<br />"
;
}
dojo.event.connect(dojo,
"loaded"
,
"init"
)
;
</
script
>
<
style type
=
"text
/
css
">
#products, #shoppingcart
{
padding:5px
;
border: 1px solid blue
;
height: 100px
;
margin-bottom:10px
;
}
#products div, #shoppingcart div
{
cursor: pointer
;
margin:5px
;
}
#products div
{
border: 1px solid green
;
float: left
;
width:90px
;
height:90px
;
}
#shoppingcart div
{
border: 1px solid green
;
}
</
style
>
</
head
>
<
body
>
<
div id
=
"products"
>
<
div id
=
"
1
">Pierwszy produkt</div>
<
div id
=
"
2
">Drugi produkt</div>
<
div id
=
"
3
">Trzeci produkt</div>
</
div
>
<
div id
=
"shoppingcart"
></
div
>
<
div id
=
"debug"
></
div
>
</
body
>
</
html
>
3/2007
Narzędzia
56
dzamy galerią obrazków. Zaraz po rozpako-
waniu źródeł widzimy, iż scriptaculous jest
dużo lżejszy od dojo. Całość (wraz z wymaga-
nym Prototype) zajmuje około 200KB. Potrze-
bujemy folderu lib (który zawiera Prototype)
oraz src, gdzie znajdują się wszystkie bibliote-
ki. Script.aculo.us podobnie jak dojo pozwala
załadować część z nich. Robimy to poprzez do-
danie parametru
?load
w ścieżce – nazwy po-
dajemy po przecinku. Potrzebne nam będą ef-
fects
oraz dragdrop. Na Listingu 2. znajduje się
przykładowy skrypt.
Metoda onUpdate umożliwia sprawdzenie
kolejności ułożenia elementów, możemy np.
na bieżąco w tle wysyłać Ajaxem informacje
do serwera, aby w bazie zapisać kolejność ele-
mentów. Konstruktor Sortable przyjmuje kil-
kanaście ciekawych parametrów takich jak:
tag
– tag elementów, jakie mają być sortowa-
ne między sobą, overlap – parametr określają-
cy czy lista ma się sortować poziomo czy pio-
nowo oraz handle – definicję obszaru, za któ-
ry można złapać przenoszone elementy. Cieka-
wostką jest, że jedynie Scriptaculous radzi so-
bie (i to również nie do końca, bo tylko w Fire-
foksie) z takimi listami, które zostały umiesz-
czone w elementach z ustawionym
overflow:
scroll
.
Scriptaculus pozwala również tworzyć ko-
lejki efektów – można łączyć elementy i two-
rzyć skomplikowane animacje. Bardzo dużym
plusem jest czytelna dokumentacja oraz ła-
twość implementacji kodu. W Internecie zna-
leźć można również wersję lite (lekką) biblio-
teki Prototype – co pozwala dodatkowo odchu-
dzić całość kodu.
MooFx
Autorzy promują tę bibliotekę, jako ultralek-
ki zestaw efektów JavaScript. Dostępne są
dwie jego wersje. Jedna oparta podobnie do
Scriptaculousa o Prototype, druga o Mooto-
ols framework. Wersja oparta o Mootools za-
wiera wszystkie moduły (można wybrać je-
dynie wymagane) i zajmuje 36KB, co jest du-
żym osiągnięciem. Biblioteka zawiera wszyst-
kie podstawowe elementy, takie jak obsłu-
ga zdarzeń, Ajaxa, efektów wizualnych ty-
pu płynne przesuwanie, tooltipów i całej ma-
sy innych. Wszystkie osoby uczulone na roz-
miar swoich skryptów powinny zwrócić uwa-
gę na tę właśnie bibliotekę. Dużym minusem
jest brak przykładów do większości z dostęp-
nych funkcji – wiadomo, że najłatwiej przy-
swoić sobie właśnie w ten sposób ich działa-
nie. Pomimo tego, dość dużo informacji zna-
leźć można na forum MooFx. Na Listingu
5. znajduje się przykładowa implementacja.
Zwykły element blokowy, który po załadowa-
niu strony rozszerza się, oraz można go prze-
nosić po ekranie. Implementacja całości jest ła-
twa, kod jest przyjemny, problemem jest jedy-
nie znalezienie w dokumentacji odpowiedniej
składni poleceń.
Listing 2. Sortowalne obrazki w Script.aculo.us
<
!DOCTYPE html PUBLIC "
-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/
xhtml1/DTD/xhtml1-transitional.dtd">
<
html xmlns
=
"http:
//
www.w3.org
/
1999
/
xhtml
" xml:lang="
en
" lang="
en
">
<
head
>
<
title
>
Sortable test
</
title
>
<
meta http-equiv
=
"content-type"
content
=
"text
/
html
;
charset
=
utf-
8
" />
<
script src
=
"lib/prototype.js"
type
=
"text
/
javascript
"></script>
<
script src
=
"src/scriptaculous.js?load=effects,dragdrop"
type
=
"text
/
javascript
"></script>
<
style type
=
"text
/
css
" media="
screen
">
#images
{
padding:5px
;
}
#images img
{
margin:5px
;
border: 2px solid #dedede
;
}
</
style
>
</
head
>
<
body
>
<
div id
=
"images"
>
<
img id
=
"image_1"
src
=
"
1.
jpg
" />
<
img id
=
"image_2"
src
=
"
2.
jpg
" />
<
img id
=
"image_3"
src
=
"
3.
jpg
" />
<
img id
=
"image_4"
src
=
"
2.
jpg
" />
<
img id
=
"image_5"
src
=
"
3.
jpg
" />
<
img id
=
"image_6"
src
=
"
2.
jpg
" />
<
img id
=
"image_7"
src
=
"
3.
jpg
" />
</
div
>
<
div id
=
"debug"
></
div
>
<
script type
=
"text
/
javascript
" language="
javascript
">
// <![CDATA]
// tworzenie listy sortowalnej
Sortable.create(
"images"
,
{
tag:
'img'
,overlap:
'horizontal'
,constraint: false, onUpdate:function()
{
$(
'debug'
).innerHTML
=
(Sortable.serialize(
'images'
))
;
}
}
)
;
// ]]>
</
script
>
</
body
>
</
html
>
Listing 4. Jak ustawić event, do niezaładowanego obiektu?
Event.observe(window,
'load'
, function()
{
Event.observe(
'myForm'
, 'submit
', doSomething);
}
)
;
Listing 3. Obsługa wydarzeń w Prototype.
<
form action
=
”form.php” id
=
”myForm” method
=
”post”
>
...
</
form
>
...
Event.observe(
'myForm'
, 'submit', doSomething)
;
również znakomitych narzędzi do Ajaxowej ob-
sługi formularzy.
Script.aculo.us
Scriptaculous to biblioteka skryptów oparta
o Prototype. Podobnie do Dojo zawiera ma-
sę modułów ułatwiających pracę z JavaScrip-
tem. Wykonajmy przykładowy skrypt oparty
o Scriptaculous. Niech będzie odpowiedzial-
ny za przenoszenie, zmianę kolejności, obraz-
ków w galerii. Może być to przydatne w sys-
temie zarządzania treścią, w którym zarzą-
JavaScript
Yahoo User Interface Library
Yahoo również przygotowało interfejs wspo-
magający budowę aplikacji opartych o techno-
logie takie jak DOM, DHTML czy AJAX. Naj-
większym plusem tego interfejsu jest na pewno
ogromne zaplecze Yahoo – najlepiej przygoto-
wane przykłady, świetna dokumentacja (na stro-
nie internetowej dział YUI Theater z wykładami
i całą otoczka związana z biblioteką). Nie zmie-
nia to faktu, iż podobnie do Dojo, pomimo funk-
cjonalności na najwyższym poziomie oraz bar-
dzo dobrego wsparcia Yahoo, całość zajmuje po-
nad 3,5MB. Na szczęście odpowiednia konfigu-
racja całości może pozwolić nam na osiągnięcie
kompromisu. Nawet, jeśli paczka nie przypadnie
nam do gustu, to ogrom informacji, jakie można
znaleźć na stronie domowej projektu jest godny
przyswojenia.
Po stronie php
Jest kilka bibliotek napisanych po stronie php, uła-
twiających tworzenie aplikacji opartych o technolo-
gię Ajax. Za najpopularniejszy uznać możemy Sa-
jax, godnym uwagi jest również Pear::Html::Ajax.
Dostarczają one jednak jedynie wygodnego interfej-
su do komunikacji pomiędzy php i JavaScriptem, a
nie tak jak reszta biblioteki efektów wizualnych.
JAKUB SACHA
Autor z technologiami internetowymi ma stycz-
ność od około 4-5 lat. Początkowo programowa-
nie traktował jako pasję, ale aktualnie pracuje ja-
ko programista w bytomskiej firmie NylonCoffee.
Kontakt z autorem: jakub@sacha.pl
Listing 5. Przykładowy skrypt efektów wizualnych wykonany za pomocą MooFx
<
!DOCTYPE html PUBLIC "
-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<
html xmlns
=
"http:
//
www.w3.org
/
1999
/
xhtml
" xml:lang="
en
" lang="
en
">
<
head
>
<
title
>
movment test
</
title
>
<
meta http-equiv
=
"content-type"
content
=
"text
/
html
;
charset
=
utf-
8
" />
<
script src
=
"mootools.js"
type
=
"text
/
javascript
"></script>
<
script type
=
"text
/
javascript
" language="
javascript
">
window.
onload
=
function()
{
$(
'element'
).makeDraggable()
;
var
wEffect
=
$(
'element'
).effect(
'width'
,
{
duration:
1000
,
transition: Fx.Transitions.linear
}
)
;
var
hEffect
=
$(
'element'
).effect(
'height'
,
{
duration:
1000
,
transition: linear
}
)
;
wEffect.start(
10
,
300
)
;
hEffect.start(
10
,
300
)
;
}
;
</
script
>
<
style type
=
"text
/
css
" media="
screen
">
#element
{
width:10px
;
height:10px
;
border: 1px solid blue
;
}
</
style
>
</
head
>
<
body
><
div id
=
"element"
></
div
></
body
>
</
html
>
Ciekawe linki
• http://ajaxian.com/ - skarbnica wiedzy
dotyczącej JavaScript'u,
• http://www.prototypejs.org/ - strona do-
mowa framework'a Prototype,
• http://dojotoolkit.org/ - strona domowa
kolejnego świetnego zestawu narzędzi
JavaScript,
• http://script.aculo.us/ - biblioteka efek-
tów napisana na podstawie Prototype,
• http://moofx.mad4milk.net/ - biblioteka
efektów, w której autorzy postawili na
lekkość kodu,
• http://developer.yahoo.com/yui/ - Yahoo
User Interface Library,
• http://codinginparadise.org/projects/
dojo_offline/screencast_02_26_2007/
screencast_02_26_2007.html – wersja
demonstracyjna aplikacji opartej o do-
jo.storage.
R
E
K
L
A
M
A