Az HTML tag stílusának automatikus felülírása javascripttel

Bizonyára mindenki észlelte már, hogy egy egyszerű checkbox is annyi féle képpen nézhet ki, ahány böngészó, meg operációs rendszer együttvéve.

Kézenfekvő tehát, hogy saját stílust alakítsunk ki, de amint elővesszük a szokásos css fájlunkat pl. egy checkboxnál, az nem fog működni.
Mielőtt szomorúan tudomásul vennénk, hogy bizony lehetetlenre vállalkoztunk, elárulom, hogy van az a trükk, amivel megoldható ez a probléma is.

Először is, vagy egy css-sel alakítjuk ki a stílusunkat, ami nem jó, hisz megint ahány böngésző, annyi módon fogja megjeleníteni.
Célszerű tehát csak az alapdolgokat css-ben elkészíteni, a többit pedig bitképpel…a mi lehet akármilyen bonyolult.

Tehát jelen esetben szerkesszünk egy 24×96-os checkbox.png-t, amelyben 4 24×24-es ikont fogunk tárolni (1) normál, 2) nem engedélyezett, 3) kipipált, 4) kipipált, de nem engedélyezett). Az ikonok közepét részint átlátszónak hagyjuk, hogy mintegy üvegként látszódjon alatta a háttér, valamint, ha az egeret felé húzzuk, akkor új hátteret adhassunk neki.
Ettől jól fog kinézni. Természetesen bonyolultabbat is lehet csinálni és külön lehet definiálni az egér lenyomását, felengedését, úgy, ahogy három állást is meghatározhatunk, sőt elvileg animálhatjuk is, ha nem sajnáljuk rá az erőforrást.

Ezt követően a szokott módonkészítsük el a stíluslapunkat.

{code type=css}input[type=checkbox] {
display: none;
}

.checkbox {
width: 24px;
height: 24px;
margin: 2px;
background: url(image/checkbox.png) no-repeat;
position: relative;
display: block;
clear: left;
float: left;
}

.checkbox:hover {
background-color: #A0A0FF;
border: 0px solid #7070FF;
border-radius: 5px;
}

.checkbox[disabled=true]:hover {
background-color: transparent;
}

.checkbox[disabled=true] {
background-position: 0 -24px;
}

.checkbox[checked=true] {
background-position: 0 -48px;
}

.checkbox[disabled=true][checked=true] {
background-position: 0 -72px;
}{/code}

Az első “utasítás” nagyon fontos, hisz a trükknek az első része az lesz, hogy láthatatlanná teszzük az összes (vagy esetleg a kijelölt) alapértelmezett checkboxot.

A checkboxunk – mely láthatólag checkbox osztály néven fog futni – 24×24-es méretű lesz és az image könyvtárban elhelyezett checkbox.png fogja meghatározni.
Mivel javascriptet használunk és a hátteret is felülírhatjuk működés közben, ezért akár menet közben stílust is válthatunk. De ez utóbbit most hagyjuk.

A hover státuszjelzővel határozzuk meg azt, hogy mi történjen amikor rámutatunk az egérrel. Jelen esetben egy lekerekített hátteret adunk hozzá, mely alulról “kivilágít”.
Vigyázni kell azonban, hogy, ha a checkboxunk nem engedélyezett akkor a háttér átlátszó legyen.

A többi esetben a hátteret a kijelölt terület alá kell mozgatni. Ezért kell vigyázni, hogy a méret pont akkorára legyen definiálva, mint a bitképben lévő ikon.

Fontos megjegyezni, hogy a HTML-ben állapotokat “true/false” módon adjuk meg, mert a css fájlban nem deklaráltunk minden változatot (állapot érték nélkül, állapot az állapot, mint értékkel). Gondoljunk csak bele, hogy a legutolsó esetben már nem kevesebb, mint 9 kombináció lenne, ráadásul az sem mindegy, hogy milyen sorrendben adjuk meg az aktuális állapotokat, hisz mindig a legutolsó lesz érvényben és ha pl. a mostani legutolsó állapotban definiáljuk a “disabled”-et, akkor azt fogja alkalmazni a legelső helyen definiált “disabled=true”-ra is. Tehát a “disabled=true”-nak mindig a disabled után kell lennie. Tehát egyszerűbb a felhasználónak utasítást adni. 😉

Jöhet a javascript, ami mindennek a lelke.

{code type=javascript}var CustomFormClass = function CustomFormClass(){
var inputElements = document.getElementsByTagName(‘input’);
for(i = 0; i < inputElements.length; i++){ input = inputElements[i]; if (input.type == 'checkbox'){ span = document.createElement('span'); span.className = 'checkbox'; CustomFormClass.inputChange(input,span); input.parentNode.insertBefore(span,input); span.onclick = function(){CustomFormClass.spanClick(input,span);}; } } };CustomFormClass.inputChange = function(input,span){ span.setAttribute('disabled',input.disabled?'true':'false'); span.setAttribute('checked',input.checked?'true':'false'); }CustomFormClass.spanClick = function(input,span){ if (!input.disabled) { input.checked = input.checked?false:true; CustomFormClass.inputChange(input,span); input.onchange(); } }window.onload = CustomFormClass;{/code}

Egy “CustomFormClass” osztályt definiálunk és minden függvényt statikusan, mert csak egy objektumra lesz szükségünk.

A következő lépés az, hogy a “getElementsByTagName” segítségével összegyűjtsük a HTML oldalról az össze input taget. Nekünk viszont csak a checkbox típusúakra lesz szükségünk, így kivállogatjuk őket.
Minden ilyen input tag elé beszúrunk egy span taget. Miután az input eltűnik csak ez fog látszódni és ezt fogjuk úgy kezelni, mintha a checkbox lenne és “összekötjük” az eredeti nem látszó checkboxszal. Ez a következő trükk.

A spanokat checkbox osztálynévvel látjuk el, hogy a stíluslapokat a rendszer alkalmazza rájuk.
Ezt követően lekérdezzük a checkboxok állapotait, melyet a HTML kód tartalmaz és alkalmazzuk a spanokra. Itt a checkboxok igaz/hamis értékeit kell átírni sztringekre és hozzáadni a spanokhoz.
Beillesztjük a helyére a spanokat, majd hozzákötünk egy egérkattintásra lefutó függvényt, mely a checkboxoknál megcseréli az igaz és hamis értékeket, alkalmazza a spanokra és meghívja a változás történt a checkboxban függvényt, hogy a rendszer aktualizálja a checkboxokra is. Persze mindezt csak akkor, ha a checkbox használata engedélyezett.

Itt megint elmondom, hogy tetszőleges bonyolultságúra lehet csinálni a kódot. Definiálhatjuk külön az egérgomb lenyomását, felengedését (mint a hagyományos gombok esetében) és bármely függvényt átmappelhetünk a másik elemre.

Végül hozzuk létre az osztályt.
Célszerű ezt az onload window metódussal, de ezt a jelenlegi formában nyilván csak akkor tegyük meg, ha csak a mi függvényünknek kell lefutnia. Ha több is van, akkor a saját függvényünkbe be kell ágyazni, hogy mind lefuthasson.

És végezetül a nem túl bonyolult HTML kód.

{code type=html}


az én checkboxom

{/code}

Látható, hogy maga a kód semmivel nem tér el a hagyományos checkbox megjelenítési módtól, így a most megírt függvényt/kinézetet a body-ban lévő kód változtatása nélkül lehet alkalmazni bármely “oldalra”. Sőt a php sem zavarja, mert a függvényünk a kész kódon, kliens oldalon fut.

Vélemény, hozzászólás?