Objavljeno: 31.3.2005 08:37 | Avtor: Uroš Mesojedec | Monitor Oktober 2004

Dinamične zvijače

Bolj privlačne spletne strani lahko pripravimo tudi s pomočjo samih odjemalcev.

Spletni brskalniki počasi postajajo eni izmed najbolj izpopolnjenih programov za računalniška namizja, v njih pa prebijemo vse več časa. Z novimi izboljšavami, ki jih je prinesel razvoj tehnologij, kot so HTML, CSS, javascript in DOM, so spletne strani pripravljene za izdelavo tudi bolj zapletenih, dinamičnih uporabniških vmesnikov. Kljub prevladi spletnega brskalnika Internet Explorer (IE) se konkurenca ne da in zadnje čase celo znatno povečuje svoj tržni delež [1]. Microsoft je prav zaradi tega že preklical svojo odločitev, da bo IE poslej le še sestavni del Oken, in znova obudil njegov razvoj v obliki samostojnega izdelka. Tako si lahko v brskalnikih kmalu obetamo še večje zmogljivosti. Posebej pomembni bosta tehnologiji SVG, s katero bo mogoče prikazovati dinamično, vektorsko grafiko (npr. prilagodljiv tortni grafikon), in nastajajoča XForms, ki bo spletne strani po uporabnosti in preprostosti uporabe izenačila z namenskimi uporabniškimi programi.

Dinamični HTML

Preden omenjeni tehnologiji dozorita in postaneta dostopni večini spletnih uporabnikov, pa si lahko ogledamo uporabo dinamičnega HTML. Kot vemo, je HTML označevalni jezik za pripravo spletnih strani. Spletna stran v HTML pa je statična, kar pomeni, da se njena podoba ne spreminja. Uporabnik tako nalaga stran za stranjo iz strežnika, ki mu pripravlja vsebino, skladno njegovim izbiram. Programiranje strežnika je danes prevladujoč način izdelave interaktivnih spletnih programov, saj nam omogoča, da na enoten način obravnavamo najrazličnejše odjemalce. Strežnik s pomočjo posebnega programa, glede na informacije, ki jih ima, izgradi spletno stran v čistem HTML in jo posreduje brskalniku.

Velikokrat pa tak pristop ni optimalen. Prva težava se skriva v samem protokolu HTTP. Vsaka sprememba spletne strani zahteva vnovično povezovanje brskalnika s strežnikom, ki pripravi vsebino nove strani in jo prek omrežja pošlje nazaj. Ker protokol ne ohranja stanja (stateless protocol), je treba ob vsaki povezavi odjemalca s strežnikom ugotavljati, kdo nas je obiskal in kaj je morda že počel na našem spletišču. Druga težava se skriva v kompleksnosti izgradnje prijazne spletne strani na strani strežnika. Če želimo izkoristiti najrazličnejše predstavitvene zmožnosti sodobnega HTML in povezanih tehnologij, bomo spletno stran v strežniku kar nekaj časa gradili, to pa zna biti v razmerah visokega obiska in hude obremenitve celo ozko grlo celotnega sistema.

Na drugi strani so spletni brskalniki čedalje zmogljivejši in postajajo zmogljiva podlaga za razvoj nove programske opreme (application platform). Zakaj ne bi izkoristili njihovih zmožnosti in obiskovalcu ponudili še boljše uporabniške izkušnje, hkrati pa razbremenili strežnik in za povrh še popravili odzivnost strani?

Pomaga nam lahko dinamični HTML. Na vrhuncu prve bitke v vojni brskalnikov sta oba rivala neusmiljeno tekmovala drug z drugim, žal na rovaš spletnih razvijalcev, ki so različne oblike dinamičnega HTML z gnusom zavrgli, saj so bile nezdružljivosti med brskalniki velikanske in velikokrat nepremostljive. Na srečo je v minulih letih nekaj reda le uspelo vpeljati organizaciji W3C (World Wide Web Consortium, http://w3c.org/), katere standarde je posvojila večina Microsoftove konkurence, tako da jih je bil na koncu prisiljen nekoliko bolj zvesto izdelati tudi v IE.

Današnje stanje pri odjemalcih, ki se sicer od države do države razlikuje, nam omogoča, da brez posebnih zadržkov posvojimo nov, dinamični HTML, ki bi ga najlaže opisali z naslednjo enačbo:

dinamični HTML = HTML + CSS + DOM + javascript

Vse našteto so standardi (W3C ali ECMA), ki so v sodobnih in prevladujočih različicah spletnih brskalnikov dovolj dobro podprti, da jih lahko z nekaj previdnosti uspešno uporabimo na javnih, široko dostopnih spletiščih. Mimogrede omenimo, da je za doseganje najširše populacije pri oblikovanju spletišča še vedno najvarneje upoštevati zaslonsko ločljivost 800 × 600 pik (ki, odvisno od "okraskov" brskalnika in namizja, pomeni uporabno površino enega zaslona zgolj še 760 × 420 pik ali celo manj), za barve pa nas ni treba več skrbeti, saj ima velika večina uporabnikov vsaj visoko barvno ločljivost (na tisoče barv). Več o stanju pri odjemalcih najdete v [1].

Povezovanje dogodkov

Moč in preprostost rabe dinamičnega HTML nam lahko pokaže naslednji zgled:

<TABLE CELLSPACING="0" CELLPADDING="10" BORDER="0">

<TR  onmouseover="this.style.backgroundColor='silver'"

onmouseout="this.style.backgroundColor=''">

<TD>200</TD><TD>030</TD><TD>050</TD>

</TR>

<TR  onmouseover="this.style.backgroundColor='silver'"

onmouseout="this.style.backgroundColor=''">

<TD>100</TD><TD>010</TD><TD>540</TD>

</TR>

<TR  onmouseover="this.style.backgroundColor='silver'"

onmouseout="this.style.backgroundColor=''">

<TD>500</TD><TD>250</TD><TD>620</TD>

</TR>

<TR  onmouseover="this.style.backgroundColor='silver'"

onmouseout="this.style.backgroundColor=''">

<TD>140</TD><TD>800</TD><TD>010</TD>

</TR>

</TABLE>

Z nekaj skriptne kode, ki smo jo uporabili za odziv na premik miške preko vsake posamezne vrstice tabele, lahko dinamično prilagajamo stran, ki sama osvetljuje vrstice tabele, ko se z miško premikamo preko nje.

Predmetni model DOM nam omogoča, da iz kode v javascriptu nadziramo vsako značilnost sloga posameznega elementa, kot da bi ga nastavili s pomočjo slogov CSS. Vsako določilo CSS lahko prevedemo v lastnost DOM, pravilo pa je takšno, da več-besedne zveze določil sloga spremenimo v eno simbolično ime, zapisano z (nižjo) "kameljo" velikostjo (camel case). Tako se je npr. določilo sloga "background-color" spremenilo v lastnost DOM "backgroundColor".

Učinek dinamičnega HTML.

Zgled lepo pokaže učinkovitost dinamičnega HTML, vendar ima veliko pomanjkljivost. Če bi na strani imeli veliko število tabel, vsaka pa bi imela precejšnje število vrstic, bi priprava takšne strani npr. na strežniku trajala kar nekaj časa, hkrati pa bi se zelo povečala velikost kode HTML, ki bi morala preko omrežja potovati od strežnika do odjemalca. Za povrhu lahko odjemalec skriptne kode sploh ne podpira in bo ves trud zaman!

Zakaj ga torej ne bi vprašali in primerno zaposlili, če ustreza našim potrebam, brez da bi dodatno obremenjevali strežnik in prenosne poti? Takole je videti popravljen zgled:

<TABLE CELLSPACING="0" CELLPADDING="10" BORDER="0">

<TR>

<TD>200</TD><TD>030</TD><TD>050</TD>

</TR>

<TR>

<TD>100</TD><TD>010</TD><TD>540</TD>

</TR>

<TR>

<TD>500</TD><TD>250</TD><TD>620</TD>

</TR>

<TR>

<TD>140</TD><TD>800</TD><TD>010</TD>

</TR>

</TABLE>

<SCRIPT>

// prijavimo dogodek vsem vrsticam vseh tabel

if ( document.getElementsByTagName ) {

var vrstice = document.getElementsByTagName("TR");

for ( var i = 0; i < vrstice.length; i++ ) {

vrstice[i].onmouseover = obarvaj;

vrstice[i].onmouseout = razbarvaj;

}

}

// odzivni funkciji morata ugotoviti vir dogodka

function izvir(e) {

if ( !e ) e = window.event;

var clen = null;

if ( e.target ) clen = e.target;

else if ( e.srcElement ) clen = e.srcElement;

if ( clen.tagName == "TD" ) clen = clen.parentNode;

return clen;

}

// obarvamo vir dogodka

function obarvaj(e) {

var clen = izvir(e);

if ( clen ) clen.style.backgroundColor = "silver";

}

// razbarvamo vir dogodka

function razbarvaj(e) {

var clen = izvir(e);

if ( clen ) clen.style.backgroundColor = "";

}

</SCRIPT>

Preden razčlenimo skriptno kodo, si oglejmo zgradbo spletne strani. Predmetni model DOM ponazori celotno spletno stran kot drevo medsebojno povezanih členov. Za naš zgled (če bi analizirali celotno datoteko HTML) je delno drevo DOM prikazano na sliki 2.

Delno drevo DOM za člene spletne strani zgleda.

Oznake HTML so v popravljenem zgledu brez dodatkov z opisi reakcij na dogodke. Skriptna koda, ki sledi na koncu, poskrbi za čisto vsako vrstico vseh tabel na spletni strani, seveda le, če je brskalnik dovolj sposoben. Test opravi klasična zvijača, preverjanje predmetov. Z naslednjim pogojem:

if ( document.getElementsByTagName ) { }

preprečimo, da bi se koda izvedla v brskalnikih, ki ne podpirajo temeljne funkcije DOM, ki jo zahteva naš zgled. Javascript namreč za člane razredov, ki jih ne podpira, vrne neresnico. Metoda DOM getElementsByTagName() vrne vse člene spletne strani, ki ustrezajo podani oznaki, kot polje, po katerem se sprehodimo z zanko for, kjer vsakemu členu nastavimo odziv na izbrana dogodka. Kogar uporaba DOM zanima podrobneje, si lahko ogleda [2].

Dogodka sta silno preprosto kodirana, edina posebnost je ugotavljanje izvira dogodka. Žal tu izbruhnejo nezdružljivosti med izvedbami DOM v priljubljenih brskalnikih. S pomočjo nasvetov zelo zanimivega in uporabnega spletišča Quirksmode.org ([3]) smo lahko pripravili posebno funkcijo, ki zna ugotoviti izvir dogodka v večini priljubljenih brskalnikov. Potrebno je bilo še nekaj sprehajanja po drevesu členov, saj je dejanski izvir dogodka posamezna celica tabele (kot jo določa oznaka <TD>), zato moramo najti njenega starša, v našem primeru vrstico (oznaka <TR>).

Izgradnja kazala

Na zelo podoben način lahko na strani odjemalca poskrbimo še za marsikaj. Slogi CSS so dokončno podpisali smrtno obsodbo nemogoči slogovni oznaki, <FONT>, in znova vrnili veljavo tradicionalnemu označevanju naslovov v besedilu z oznakami <Hn>. Označevanje z oznakami <Hn> se nam izplača tudi zato, ker bodo različni iskalniki take strani samodejno kategorizirali in iz naslovov razbrali ključne besede.

Če smo spletne strani res pazljivo opremili z vsebino, ki naslove ustrezno označuje, zakaj ne bi s pomočjo dinamičnega HTML poskrbeli za pregledno kazalo, ki ga lahko dodamo na vsako stran, in to brez dodatnega obremenjevanja strežnika? Najprej si pripravimo ustrezno vsebino. V datoteko HTML na izbrano mesto dodamo prazen blok za kazalo. Za označevanje bloka vsebine uporabljamo oznako <DIV>:

<DIV id="kazalo"></DIV>

<H1>Naslov</H1>

<P>Lorem ipsum dolor sit...</P>

<H2>Podnaslov 1</H2>

<P>Maecenas lacus nisl, ...</P>

<H3>Pod-podnaslov 1</H3>

<P>Sed vitae dui. Maecenas molestie...</P>

<H3>Pod-podnaslov 2</H3>

<P>Aenean enim. Mauris condimentum...</P>

<H2>Podnaslov 2</H2>

<P>Nulla massa felis, consectetuer ac...</P>

Blok, kamor želimo uvrstiti kazalo, je enolično označen z imenom "kazalo". Brskalniki, ki ne podpirajo dinamičnega HTML, bodo prikazali zgolj neviden, prazen blok, naprednejši brskalniki pa bodo vanj čisto sami uvrstili hierarhično kazalo vsebine spletne strani. Znova nam pomagata DOM in javascript, ki se jima bodo v tem zgledu priključil še slogi CSS.

Ker bo programske kode nekaj več, dodajmo v glavo povezavo na zunanji datoteki s kodo in slogi ter pokličimo ustrezen dogodek znotraj oznake telesa strani, <BODY>:

<HTML>

<HEAD>

<TITLE>Kazalo</TITLE>

<STYLE type="text/css">

@import url(slogi.css);

</STYLE>

<SCRIPT language="javascript" src="skript.js"></SCRIPT>

</HEAD>

<BODY onload="kazalo()">

(vsebina)

</BODY>

</HTML>

V datoteki "skript.js" je naslednja koda:

function kazalo() {

if ( document.getElementById ) {

var k = document.getElementById("kazalo");

if ( k ) {

var naslovi = new Array();

var cleni = document.body.childNodes;

for ( var i = 0; i < cleni.length; i++ )

if ( cleni[i].nodeName.substr(0,1) == "H" )

naslovi.push(cleni[i]);

if ( naslovi.length > 2 )

for ( var i = 0; i < naslovi.length; i++ ) {

var vez = document.createElement("A");

vez.innerHTML = naslovi[i].innerHTML;

vez.href = "#kazalo_" + i;

vez.className = "kazalo" +

naslovi[i].nodeName.substr(1,2);

k.appendChild(vez);

var sidro = document.createElement("A");

sidro.id = "kazalo_" + i;

naslovi[i].parentNode

.insertBefore(sidro,naslovi[i]);

}

}

}

}

Prvo preverjanje se nanaša na prisotnost elementa z oznako "kazalo". Vanj bomo namreč dodali povezave na vse naslove, zato ne gre brez njega.

Da bo kazalo uspešno narejeno, moramo takoj zatem vzpostaviti polje vseh naslovov. Po dogovoru so naslovi označeni z eno od oznak <Hn> (<H1>, <H2>, ... <H6>). Če naletimo na tako, jo dodamo v polje naslovi:

var naslovi = new Array();

var cleni = document.body.childNodes;

for ( var i = 0; i < cleni.length; i++ )

if ( cleni[i].nodeName.substr(0,1) == "H" )

naslovi.push(cleni[i]);

Kazalo bomo gradili, če smo našli vsaj tri naslove. Če je pogoj izpolnjen, se s pomočjo zanke sprehodimo čez vse. Za vsak naslov ustvarimo novo vez:

var vez = document.createElement("A");

Njeno besedilo preprosto preslikamo iz vsebine obstoječega naslova:

vez.innerHTML = naslovi[i].innerHTML;

Zatem določimo njen cilj, ki ga enolično določimo s poimenovanim sidrom:

vez.href = "#kazalo_" + i;

Znak # določa povezavo na sidro, njegovo ime pa bo kazalo_<n>, pri čemer je <n> enolična zaporedna številka naslova. Enoličnost imen sider je tako zagotovljena.

Zatem poskrbimo še za obliko prikaza. Ker želimo hierarhični prikaz naslovov, vsakemu priredimo slog, skladen s pomembnostjo naslova. Naslednja vrstica poskrbi, da imajo vsi posamezni nivoji kazala prirejen drugačen slog:

vez.className = "kazalo" +

naslovi[i].nodeName.substr(1,2);

Ko je nova vez dokončno izdelana, jo vstavimo v pripravljeni blok s kazalom:

k.appendChild(vez);

Delo pa s tem še ni končano. Da bodo vezi iz kazala zares delovale, moramo pred naslove postaviti sidra. To stori nadaljevanje kode. Ustvarimo nov člen A, ki tokrat ne bo rabil za vez, temveč za poimenovano sidro (named anchor), katerega ime se mora ujemati s prej določenim ciljem vezi:

var sidro = document.createElement("A");

sidro.id = "kazalo_" + i;

Za konec poimenovano sidro še uvrstimo na pravo mesto, tik pred naslov:

naslovi[i].parentNode

.insertBefore(sidro,naslovi[i]);

Če bi zgled preizkusili v takem stanju, bi lahko ugotovili, da sicer izgradi kazalo, a je podoba strani zelo uboga, skoraj neuporabna, kot ponazarja slika 3.

Podoba strani z izgrajenim kazalom, a brez slogov.

Končni kamenček v mozaiku so še slogi CSS, ki jih moramo določiti. Delo smo pač razdelili na vsebino, kodo in sloge, kot se spodobi za sodobno spletno stran. Slogi, shranjeni v ločeni datoteki "slogi.css", bi lahko bili naslednji:

BODY {

font-family: helvetica,sans-serif;

font-size: 10pt;

}

DIV#kazalo {

float: right;

width: 200px;

padding: 5px;

background-color: #def;

border: solid 1px navy;

}

A.kazalo1, A.kazalo2, A.kazalo3 {

display: block;

}

A.kazalo1 {

font-weight: bold;

}

A.kazalo2 {

margin-left: 10px;

}

A.kazalo3 {

margin-left: 20px;

}

Ključne dele smo označili krepko. Za blok z oznako "kazalo" si želimo, da leži na desni, besedilo pa naj ga obliva. To dosežemo z določilom float. Oznake, ki so v kazalu, za katere je koda že določila sloge "kazalo1", "kazalo2" itn., moramo poskrbeti nekoliko drugače. Najprej moramo spremeniti njihov prikaz (display) iz tekočega (inline) v bločni (block), da bo vsaka povezava v svojem bloku. Zatem uredimo še hierarhijo, in sicer tako, da podrejene naslove bolj zamaknemo (margin-left). Seveda bi morali pripraviti še več slogov (kazalo4, kazalo5...), če želimo podpreti tudi naslove <H4> in manjše.

S pomočjo slogov je stran popolnoma drugačna (slika 4).

Prenovljena podoba strani s pomočjo slogov.

Namigi

Za konec si oglejmo še eno zanimivo možnost izkoriščanja odjemalca za izboljšanje uporabniške izkušnje. Pripravili bomo lastno ogrodje za prikaz namigov (tooltips). Ti namigi pa ne bodo kar tako, v resnici bodo miniaturne spletne strani, torej lahko v njih prikažemo praktično karkoli.

Nekatere oznake HTML nam že omogočajo dodajanje namigov. S pomočjo dodatnega določila title lahko namig dodamo vsaki povezavi ali sliki:

<A href="dokument.html" title="zanimiva povezava">...</A>

Taki namigi so hitra in učinkovita rešitev, dokler si ne zaželimo česa posebnega. Zgled take posebnosti bi bilo lahko npr. opozarjanje na vezi, ki vodijo do dokumentov PDF (Portable Document Format, zapis programa Adobe Acrobat). Verjetno bi si želeli, da uporabnika nanje opozorimo. Dodajanje določila title ni najboljša rešitev, saj se namig najverjetneje prikaže prepozno in bo uporabnik povezavo že pred tem aktiviral. Poleg tega lahko klasični namig prikaže zgolj besedilo, mi pa bi si morda zaželeli v namigu prikazati še ikono vrste dokumenta, morda celo povezavo do programa za pregledovanje tovrstnih datotek.

Za zgled smo v besedili prejšnjega zgleda vsako pojavitev besede "amet" povezali na datoteko "acro.pdf". Spet bi bil lahko strežnik ta, ki bi vsako povezavo na PDF opremil z vsemi potrebnimi dodatki, a tudi tu je bolje in učinkoviteje uporabiti dinamični HTML. V besedilo dokumenta dodamo še en blok, tokrat označen drugače:

<BODY onload="kazalo()">

<DIV id="namig"><!-- namig --></DIV>

(... preostanek vsebine ...)

</BODY>

Med sloge ("slogi.css") pa dodamo slog za novi blok, za katerega si želimo, da je skrit (visibility):

DIV#namig {

font-size: 9pt;

padding: 2px;

background: #ffc;

border: outset 1px;

visibility: hidden;

position: absolute;

z-order: 2;

}

Njegov položaj bomo določili v absolutnih koordinatah (position), poleg tega pa naj bo nad preostalo vsebino (z-order). Manjka nam še programska koda. To bomo dopisali v datoteko s skriptno kodo ("skript.js"). Za začetek dodajmo funkcijo, ki najde vse povezave na dokumente PDF in jim pripoji ustrezen dogodek:

function oznaciPDF() {

var a =    document.getElementsByTagName("A");

for ( var i = 0; i < a.length; i++ )

if (a[i].href.substr(a[i].href.length-4).toLowerCase() == ".pdf")

a[i].onmouseover = namigPDF;

}

Kot smo videli, bo prikaz namiga delo funkcije namigPDF():

function namigPDF(e) {

if ( !e ) e = window.event;

var clen = null;

if ( e.target ) clen = e.target;

else if ( e.srcElement ) clen = e.srcElement;

if ( clen )  {

namig(clen, "dokument vrste Adobe Acrobat!");

}

}

Znova lovimo izvir dogodka, zatem pa na pomoč pokličemo bolj splošno funkcijo, ki skrbi za prikaz namiga; posredovali smo ji izvir dogodka in vsebino namiga. Funkcija pa je del celotnega ogrodja za prikaz namigov, katerega koda sledi:

var namigTID = null;

function namig(clen, s) {

// prikaži namig na pravem mestu,

// če zanj obstaja blok v vsebini

var t = document.getElementById("namig");

if (t) {

t.innerHTML = s;

t.style.left = getPosX(clen) + 20;

t.style.top = getPosY(clen) + 20;

t.style.visibility = "visible";

}

// po določenem času namig skrij

if (namigTID) clearTimeout(namigTID);

namigTID = setTimeout("namigSkrij()", 2000);

}

function namigSkrij() {

document.getElementById("namig").style.visibility = "hidden";

}

function getPosX(clen) {

return( clen.offsetParent==null ?

clen.offsetLeft :

clen.offsetLeft + getPosX(clen.offsetParent) );

}

function getPosY(clen) {

return( clen.offsetParent==null ?

clen.offsetTop :

clen.offsetTop + getPosY(clen.offsetParent) );

}

function getPos(id) {

var coordinates = {x: 0, y:0};

coordinates.x = getPosX(obj);

coordinates.y = getPosY(obj);

return coordinates;

}

Ogrodje vsebuje javno spremenljivko, ki hrani sklic na časovnik (namigTID), potreben za pravočasno skrivanje že prikazanega namiga. Za prikaz namiga skrbi ustrezna funkcija. Ta najprej preveri obstoj ustreznega člena v dokumentu in mu zatem nastavi vsebino in položaj, pri tem pa si pomaga z ugotavljanjem absolutnega položaja izvira namiga, v našem primeru so to vezi na dokumente PDF. Delo opravita pomožni funkciji: getPosX() in getPosY(), ki z rekurzivnim klicem prehodita drevo DOM in seštejeta odmike vseh členov. S tem pridemo do absolutne koordinate elementa.

Na koncu funkcija za prikaz poskrbi tudi za izginotje namiga, z zakasnjenim klicem funkcije namigSkrij(). Izbrali smo čas dveh sekund (mirovanja, premik miške nad vezjo znova sproži dogodek).

Da bo reč delovala, moramo namige tudi vzpostaviti. V vsebini zato dopolnimo oznako BODY:

<BODY onload="kazalo();oznaciPDF()">

Zdaj je stran veliko prijaznejša. Namig o nenavadni povezavi se prikaže takoj, po želji pa bi ga lahko še grafično izpilili. Eden od načinov je uporaba skritega bloka, ki hrani bolj popolno oblikovano vsebino namiga. V dokument HTML dodamo neviden blok:

<DIV id="namigPDF" style="display:none">

<IMG src="pdf.gif" align="absmiddle" />

<B>Dokument PDF</B>. Potrebujete pregledovalnik

<A href="http://www.adobe.com/prodindex/acrobat/readstep.html">

Adobe Acrobat Reader</A>.

</DIV>

Kodo funkcije za prikaz namiga po posodobimo v vrstici, ki določa vsebino namiga:

function namigPDF(e) {

// ...

namig(clen, document.getElementById("namigPDF").innerHTML);

// ...

}

Videz strani med uporabo je na sliki 5.

Uporaba strani z dinamično pripravljenim kazalom in namigom.

Velike zmožnosti

Z naštetimi zgledi smo zgolj popraskali po površju. Podrobnejše spoznavanje modela DOM, slogov CSS ter njunega izkoriščanja skozi skriptno kodo CSS nam lahko razkrije še marsikatero zmožnost, s katero lahko naredimo spletne strani uporabnejše in bolj privlačne, breme priprave strani pa razporedimo med strežnik in vse bolj zmogljive odjemalce.

Viri in dodatna literatura:

[1] Browser Statistics (http://www.w3schools.com/browsers/)

[2] Gecko DOM reference (http://www.mozilla.org/docs/dom/domref/)

[3] Quirksmode.org (http://www.quirksmode.org/)

Naroči se na redna tedenska ali mesečna obvestila o novih prispevkih na naši spletni strani!

Komentirajo lahko le prijavljeni uporabniki

 
  • Polja označena z * je potrebno obvezno izpolniti
  • Pošlji