Novije i potpunije stranice pogledajte na adresi: http://www.dario-ljubesic.iz.hr/

Dario o izradi site-a: promjena stila nenametljivim javascriptom

Priblemi s prvom verzijom

Prva verzija promjene stila radi, ali kad pogledamo stranicu preglednikom koji ne podržava javascript (ili je javascript isključen), vidimo na ekranu opcije za izbor stilova, iako promjena sada ne radi. Normalno, bolje rješenje prikazuje listu stilova samo kada je promjena stilova zaista moguća.

Druga stvar koja je problematična je način na koji se pozivaju (aktiviraju) funkcije za promjenu stila. U prvoj verziji to je izvedeno u kodu same (X)HTML stranice:


<div id="styleswitcher">Izaberite stil:
<ul>
<li><a href="#" onclick="setCSS('default')">default</a></li>
<li><a href="#" onclick="setCSS('quick')">quick</a></li>
<li><a href="#" onclick="setCSS('light')">light</a></li>
</ul>
</div>

Pisanje višeslojnog koda (engl. multitier) danas se smatra obveznim pri razvoju iole složenijih aplikacija. Sličan princip, kad ga primijenimo na web stranice, pokazuje kako treba odvojiti XHTML kod (koji prikazuje značenje, semantiku našeg teksta) od CSS koda (koji definira pravila prikaza). Korak dalje je razdvajanje XHTML-a od javascript koda (kojim se definira ponašanje elemenata naše stranice).

Nova verzija

Nenametljiv javascript (engl. unobtrusive javascript) je naziv (termin) koji koristimo za označavanje javascript koda čije postojanje se u kodu XHTML stranice može vidjeti samo po naznaci vanjske (javascript) datoteke u zaglavlju (<head> dijelu) stranice. Prevedeno, na stranici imamo:


<head>
...
<script type="text/javascript" src="/js/css-switch.js"></script>
...
</head>

Samo po tome je vidljivo kako je ponašanje definirano u vanjskoj javascript datoteci. Možemo koristiti više vanjskih datoteka. Na stranici, XHTML kod za izmjenjivač stilova sada izgleda ovako:


<div id="styleswitcher"></div>

Sada definiramo pravilo prikaza (engl. CSS rule) kojim postavljamo cijeli <div> blok nevidljivim (preciznije: nepostojećim, jer ne zauzima prostor na stranici).

JavaScript kod

Izrada izbora stilova

U javascript kodu generiramo sve opcije naše liste:


function createSwitcher(my_styles) {
  var my_ul = document.createElement('ul');
  for (var i = 0; i < my_styles.length; i++) {
    var my_li = document.createElement('li');
    var my_a = document.createElement('a');
    var my_text = document.createTextNode(my_styles[i]);
    my_a.setAttribute('id', my_styles[i]);
    my_a.setAttribute('href','#');
    my_a.className = 'normal';
    my_a.onclick = function() {setCSS(this.id);};
    my_a.appendChild(my_text);
    my_li.appendChild(my_a);
    my_ul.appendChild(my_li);
  }
  return my_ul;
}

Funkcija createSwitcher ima parametar my_styles koji je zapravo polje s nazivima stilova. Funkcija kreira listu ('ul' element) i za svaki stil dodaje novi element liste ('li' element). Svaki 'li' element sadržava 'a' element (potreban zbog definiranja :hover efekta u CSS pravilima). Unutar 'a' elementa nalazi se čisti tekst (za koji se stvara poseban TextNode element). Za 'a' element definiramo atribute 'id' (jednostavan način kako 'a' element zna koji vanjski CSS treba aktivirati) i 'href' (nama nepotreban za ponašanje, ali obavezan prema specifikaciji i ispravan prikaz :hover efekta). Dodatno, definiramo njegovo ponašanje kad se aktivira (na 'click' događaj [engl. event]). Definiram CSS klasu 'normal' kako bih mogao kontrolirati izgled trenutno aktivnog i ostalih ('normal') stilova.

Treba primijetiti kako su pojedini elementi napravljeni pozivom odgovarajućeg metoda document objekta (createElement ili createTextNode). Napravljeni elementi postoje u memoriji, ali nisu postavljeni u strukturu naše stranice. Zato treba tekst element dodati kao 'dijete' (engl. appendChild) napravljenom 'a' elementu, 'a' element treba dodati 'li' elementu, a 'li' element treba dodati 'ul' elementu.

Popis stilova

Popis stilova, koje prikazujemo korisniku, dobivamo funkcijom getSwitcherCSS. Zadatak funkcije je pokupiti imena (sadržaje 'title' atributa) svih (alternativnih) stilova (atribut 'rel' ima vrijednost "stylesheet" ili "alternate stylesheet") koji imaju 'title' atribut, a navedeni su u zaglavlju dokumenta (unutar 'head' dijela).


function getSwitcherCSS() {
var i, a, t;
var c = new Array();
for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
  t = a.getAttribute("rel");
  if((t.indexOf("alt") == 0 || t.indexOf("sty") == 0) && a.getAttribute("title")) {
    c[c.length] = a.getAttribute("title");
  }
}
return c;
}

Funkcijom getElementsByTagName dobivamo polje 'link' elemenata iz kojeg uzimamo jedan po jedan. Svi 'link' elementi nalaze se u 'head' dijelu, a njima se specificiraju odnosi dokumenta (engl. relationship) s drugim resursima. Mene zanimaju samo 'link' elementi koji imaju atribut 'rel' čiji sadržaj počinje s 'alt' ili 'sty' (puni tekst je 'alternate stylesheet' ili 'stylesheet', ali kako sada ne postoje neke druge vrijednost 'rel' elementa koje počinju s 'alt' ili 'sty', mogu provjeravati samo prva tri slova; to je nešto brže). Dodatno, elementi moraju imati atribut 'title' koji ću spremiti u polje c. Na kraju, funkcija vrati polje u kojem su stilovi (sadržaji title atributa) koji se mogu mijenjati.

Pokretanje procedure

Događaj (engl. event) 'onload' dešava se nakon što preglednik učita cijelu stranicu (sa servera, diska ili neke treće lokacije). Ako stranica sadrži element 'styleswitcher' (tj. element koji ima atribut 'id' čija vrijednost je 'styleswitcher'), treba napraviti izbornik stilova i postaviti ga na njegovo mjesto na stranici (u strukturi dokumenta). Kad je to sve napravljeno, cijelu konstrukciju treba učiniti vidljivom korisniku postavljanjem display: block CSS pravila iz javascript-a. Cijeli kod je:


var my_styles = getSwitcherCSS();
window.onload = function(e) {
  var o = document.getElementById("styleswitcher");
  if (o) {
      var my_ul = createSwitcher(my_styles);
      if (my_ul) {
        var my_text = document.createTextNode('Izaberite stil:');
        var my_title = document.createElement('div');
        my_title.appendChild(my_text);
        o.appendChild(my_title);
        o.appendChild(my_ul);
        var cookie = readCookie('style');
        var title = cookie ? cookie : getDefaultCSS();
        for (var i = 0; i < my_styles.length; i++) {
          if (my_styles[i] == title) {
            break;
          }
        }
        if (i > my_styles.length) {
          title = my_styles[0];
        }
        setCSS(title);
        o.style.display='block';
        return title;
      }
    }
  }
}

Na kraju učitavamo cookie 'style' i ako je definiran, postavljamo tu informaciju kao aktivni stil. Prije postavljanja, prvo treba provjeriti točnost informacije: u petlji prolazimo kroz sve stilove dok ne nađemo naziv stila proslijeđen cookie-jem. Ako ne postoji takav stil, aktiviraj prvi stil s popisa (my_styles[0]). Tako se pamti jednom zadani stil kroz sve stranice koje korisnik pregledava.

Aktiviranje stila

Prvi korak kod aktiviranja stila je postavljanje atributa 'disabled' svim 'link' elementima koji navode stilove. Ti elementi navedeni su u zaglavlju dokumenta, imaju atribut 'title', a 'rel' atributa mora sadržavati riječ 'style' (moguće vrijednosti su 'style' i 'alternate style'). Samo aktivan stil ima postavljen 'disabled' atribut na false, ostali na true.


function setCSS(title) {
  var a;
  for(var i=0; (a = document.getElementsByTagName('link')[i]); i++) {
    if(a.getAttribute('rel').indexOf('style') != -1 && a.getAttribute('title')) {
      a.disabled = true;
      if(a.getAttribute('title') == title) {
        a.disabled = false;
      }
    }
  }
  var o = document.getElementById('styleswitcher');
  var li;
  if (o) {
    for(var i=0; (li = o.getElementsByTagName('li')[i]); i++) {
      a = li.getElementsByTagName('a')[0];
      a.className = 'normal';
      if(a.getAttribute('id') == title) {
        a.className = 'current';
      }
    }
  }
  return false;
}

U drugom koraku potrebno je postaviti CSS atribute svim 'a' elementima kojima navodimo stilove. U 'styleswitcher' elementu, 'div'-u u kojem se nalazi cijela konstrukcija, nalazi se lista ('ul' element) koja se sastoji od članova ('li' elemenata). U svakom 'li' elementu, prvi 'a' element (teoretski, može ih biti više) sadrži naziv stila i to je element kojem definiramo stil. Aktivnom stilu dodjeljujem CSS klasu naziva 'current', dok svi ostali stilovi imaju CSS klasu 'normal'. Sada u CSS-u mogu definirati različit izgled, ovisno da li je element aktivan ili nije.

Ograničenja

Kako se sadržaj 'title' atributa svakog stila (svakog 'link' elementa koji definira alternativni stil) koristi kao 'id' atribut (vidi createSwitcher funkciju), slijedi kako je tekst u 'title' atributu ograničen pravilima koja vrijede za saržaj 'id' atributa. Prevedeno, to znači kako 'title' atribut mora početi slovom (engleskog alfabeta, bez naših slova s kvačicama), iza čega mogu slijediti druga slova [isto engleskog alfabeta :-(], brojke [0-9], crta (engl. hyphen [-]), podvlaka (engl. underscore [_]), dvotočka (engl. colon [:]) i točka (engl. period [\.]). Pa zato, kod imenovanja stilova treba upotrijebiti one dvije marke sive tvari zvane mozak.

Pogledajte

Naslovna stranica