lib.js – práca s CSS triedami

Seriál o knižnici lib.js pokračuje predstavením piatich funkcií pre prácu s CSS triedami – atribútom class="". Programovo pracovať s atribútom class je v JS dosť problematické, pretože názov vlastnosti je className, čo mnohí netušia a je treba s ním pracovať ako s textom – nie je to žiadne pole hodnôt – takže napr. na zistenie, či element má aplikovanú nejakú triedu sa používa vyhľadávanie v texte a iné metódy. Nie vždy však bývajú 100% spoľahlivé. Celú situácii zjednodušuje lib.js knižnica s ktorou ľahko pridáme, odstránime, „zameníme“, zistíme, či element má definovanú triedu a pridáme triedu za splnenia podmienky.

Pridanie/odstrá­nenie triedy

// C# syntax
void addClass(DOMString elem, DOMString className);
void addClass(HTMLElement elem, DOMString className);
void addClass(DOMString elem, DOMString className, boolean allowDuplicates);
void addClass(HTMLElement elem, DOMString className, boolean allowDuplicates);

// Java syntax
addClass(elem: DOMString, className: DOMString) : void;
addClass(elem: HTMLElement, className: DOMString) : void;
addClass(elem: DOMString, className: DOMString, allowDuplicates: boolean) : void;
addClass(elem: HTMLElement, className: DOMString, allowDuplicates: boolean) : void;

// C# syntax
void remClass(DOMString elem, DOMString className);
void remClass(HTMLElement elem, DOMString className);
void remClass(DOMString elem, DOMString className, boolean all);
void remClass(HTMLElement elem, DOMString className, boolean all);

// Java syntax
remClass(elem: DOMString, className: DOMString) : void;
remClass(elem: HTMLElement, className: DOMString) : void;
remClass(elem: DOMString, className: DOMString, all: boolean) : void;
remClass(elem: HTMLElement, className: DOMString, all: boolean) : void;

Parameter allowDuplicates funkcie addClass() určuje, či sa má trieda className pridať aj vtedy, ak ju už má element definovanú.
Parameter all funkcie remClass() určuje, či sa majú odstrániť všetky výskyty triedy aplikované na element elem. Ak nie je nastavený, odstráni sa prvý výskyt danej triedy – toto je dôležité vedieť z hladiska CSS kaskády.

Ak nie sú parameter určené, funkcie sa chovajú, akoby boli nastavené na hodnotu false.

Ukážka: funkcia SetClasses() postupne pridá/odstráni triedy elementu p aj s ukázaním funkcií parametrov allowDuplicates a all.

function SetClasses() {
  var p = getElem('p1'); // získanie referencie na odstavec

  addClass(p, 'green');
  addClass(p, 'blue');
  addClass(p, 'red');
  alert(p.className); // class="green blue red";

  addClass(p, 'red'); // nie je povolené pridanie duplikátnej triedy
  alert(p.className); // class="green blue red";

  addClass(p, 'green', true); // povolí pridanie duplikátnej triedy
  addClass(p, 'red', true); // to isté...
  alert(p.className); // class="green blue red green red"

  remClass(p, 'green'); // odstráni iba prvú triedu .green
  alert(p.className); // class="blue red green red";

  remClass(p, 'red', true); // odstráni všetky triedy .red
  alert(p.className); // class="blue green";
}

Ako sa postupne mení hodnota atribútu class="" môžete vidieť v komentároch.

Podmienené aplikovanie triedy

// C# syntax
boolean swapClass(DOMString e, DOMString c);
boolean swapClass(HTMLElement e, DOMString c);

// Java syntax
swapClass(e: DOMString, c: DOMString) : boolean;
swapClass(e: HTMLElement, c: DOMString) : boolean;

Funkcia swapClass() je veľmi vhodná na vytvorenie tzv. „on/off“ stavov. Ak triedu c má element e aplikovanú, funkcia triedu odstráni, v opačnom prípade ju pridá. Upozornenie k vnútornej implementácii funkcie si prečítajte nižšie.

Funkcia vráti true, ak element má definovanú triedu po vykonaní funkcie, false, ak triedu definovanú nemá. Návratovú hodnotu je vhodné použiť na zistenie aktuálneho on/off stavu.

Príklad:: Po kliknutí na odkaz sa čierny text a biele pozadie odstavcu #p1 zmení na červený text a žlté pozadie. Pri ďalšom kliknutí sa zmení naspäť. Príklad ukazuje použitie funkcie swapClass() na veľmi jednoduché vytvorenie (toggle) „on/off“ stavu.

<style type="text/css">
.red { color: red }
.bg-yellow { background: lightyellow }
</style>
...

<script type="text/javascript">

addLoadEvent(function() {
  addEvent('a', 'click', evt_a_click);
});

function evt_a_click(e) {
  // pri každom kliknutí sa zmení farba textu a pozadia
  var p = getElem('p1');
  swapClass(p, 'red');
  swapClass(p, 'bg-yellow');

  e.preventDefault();
}
</script>
...

<body>
  <p id="p1">test</p>
  <p><a href="#" id="a">Klik!</a></p>
</body>

Zobrazenie ukážky funkcie swapClass()

Funkcia condClass() pridá alebo odstráni triedu na základe pravdivosti parametru cond. Ak je pravdivý, trieda c bude elementu e pridaná, ak je nepravdivý, trieda bude zmazaná. Upozornenie k vnútornej implementácii funkcie si prečítajte nižšie.

// C# syntax
void condClass(DOMString e, DOMString c, boolean cond);
void condClass(HTMLElement e, DOMString c, boolean cond);

// Java syntax
condClass(e: DOMString, c: DOMString, cond: boolean) : void;
condClass(e: HTMLElement, c: DOMString, cond: boolean) : void;

Upozornenie k vnútornej implementácii swapClass() a condClass(): Funkcie pri pridávaní alebo odstraňovaní tried používajú funkcie addClass(), remClass() bez 3. parametru, čiže:

  • pri pridávaní triedy nie sú pridané duplikáty (allowDuplicates = false),
  • pri odstraňovaní triedy nie sú odstránené všetky výskyty triedy (all = false).

V prípade zložitejších prác s triedami je možné, že vám zostanú duplikáty triedy v elemente a vzniknú problémy s CSS kaskádou.

Má element definovanú triedu?

// C# syntax
int condClass(DOMString elem, DOMString className);
int condClass(HTMLElement elem, DOMString className);

// Java syntax
condClass(elem: DOMString, className: DOMString) : int;
condClass(elem: HTMLElement, className: DOMString) : int;

Funkcia hasClass() vráti počet definovaných tried className v elemente elem.

var p = getElem('p1');

remClass(p, 'red', true); // vymazanie všetkých .red tried
addClass(p, 'red', true);
addClass(p, 'blue', true);
addClass(p, 'red', true); // pridanie duplikátnej .red triedy
addClass(p, 'green', true);

alert(hasClass(p, 'red')); // element p má 2 triedy .red

Poznámka na koniec: žiadna z uvedených funkcií nevie pracovať s kolekciou (poľom) elementov. Ak chcete hromadne aplikovať triedu napr. na všetky obrázky na stránke, musíte použiť cyklus. Kód addClass(getAll('img'), 'obrazok'); nebude fungovať.