JavaScript
Børre Stenseth

Javascript og CSS

Hva

Utvikling av web-sider, eller om vi vil web-løsninger, er i økende grad avhengig av en klar oppfatning av forholdet mellom struktur, utseende og dynamikk. Disse tre aspektene er koplet til 3 teknologier: HTML, CSS og JavaScript.

HTML5 viderefører et klart fokus på struktur, og de fleste stilbaserte attributtene er borte. CSS utvikler seg stadig og har langt større fleksibilitet enn de fleste er klar over.

I denne modulen skal vi se litt på hvordan vi kan bruke JavaScript mot CSS. Du finner mer CSS og spesielt hvordan vi kan manipulere reglene inne i CSS.

JavaScript gir oss mange muligheter for å søke etter elementer i et document- eller element-objekt

De tre gamle metodene getElemenstByTagName(t), getElementByID(id) og getElementsByClassName(cls) er velkjente og operer på henholdvis elementnavn, attributte id og attributten class. Merk spesielt at den siste er fleksibel på den måten at sjekker om stringen cls er representert som en blankseparert string i class-attributten. Alle tre er metoder både i document og element.

I tillegg til disse har vi to metoder querySelectorAll(selector) og querySelector(selector). Disse forutsetter at det er satt opp en kopling mellom HTML (struktur) og CSS (utseende) og parameteren er en CSS3-selector, formulert på samme måte som vi gjør det i et stilsett. Begge er metoder både i document og element. Forskjellen er at den første returnerer alle elementene den finner, mens den andre returnerer det første. Det vil si at det gir mening å skrive f.eks.:

document.querySelectorAll('div');
document.querySelectorAll('.hilited');
// annen kolonne i tabellen med id prisliste
document.querySelectorAll('#prisliste tr>td:nth-of-type(2)');
// match på en av kommaseparert liste av class
document.querySelectorAll('.fornavn','.etternavn');

getElemenstByTagName(t) og getElementsByClassName(cls) returnerer en collection i JavaScript, mens querySelectorAll() returnerer en staticNodeList. Fordelen med den siste er at lista overlever dersom vi endrer egenskaper ved et medlem på en slik måte at det ikke lenger oppfyller kriteriene for medlemskap, f.eks. dersom vi endrer et klasse navn. Vi kan f.eks skrive:

var selected=document.querySelectorAll('.hilited');
[].forEach.call(selected, function(elt) {
	elt.className='killed';
});

Endre style direkte

Dersom elementer har attributten style, kan vi skrive Javascriptkode som endrer denne.

Dra musa over her så blir det rødt

HTML-koden er slik:

<div id="target3" style="color:blue; font-size:30px"
     class="a" onmouseover="changeStyle(event,'red','40px')" 
               onmouseout="changeStyle(event,'blue','30px')">
    Dra musa over her så blir det rødt
</div>

Javascriptfunksjonen er slik:

function changeStyle(event,clr,sze)
{
    var elt= event.target;        
    elt.style.color=clr;
    elt.style.fontSize=sze;
}

Navn på CSS-egenskaper

Når vi skal manipulere CSS-egenskaper fra javascript er det viktig å huske at CSS-egenskaper systematisk bruker - som ordskiller (font-size, background-color, page-break-before, border-top-width, etc). Dette går dårlig som identifikator i JavaScript som oppfatter - som minus. Når en egensskap skal navngis i JavaScript skrives den vanligvis slik at andre ord begynner på stor bokstav (fontSize, backgroundColor, pageBreakBefore, borderTopWidth, etc), ofte kalt camelCase.

Dra musa over her så blir bakgrunnen rød

HTML-koden er slik:

<div id="target4" style="color:blue; font-size:20px"
     class="a" onmouseover="changeBStyle(event,'red','16px')" 
               onmouseout="changeBStyle(event,'white','20px')">
    Dra musa over her så blir bakgrunnen rød
</div>

Javascriptfunksjonen er slik:

function changeBStyle(event,clr,sze)
{
    var elt= event.target;
    elt.style.backgroundColor=clr;
    elt.style.fontSize=sze;
}

Endre css class

I stedet for å arbeid direkte på stilegenskaper kan vi sette stilklasse.

Dra musa over så blir det rødt

HTML-koden er slik:

<div id="target2" 
     class="a" onmouseover="setClass(event,'b')" 
               onmouseout="setClass(event,'a')">
    Dra musa over så blir det rødt
</div>

Javascriptfunksjonen er slik:

function setClass(event,cls)
{
    var elt= event.target;
    elt.className=cls;
}

og stilsettet er slik.

<style id="mystyles2" type="text/css">
	.a{color:blue; font-size:20px}
	.b{color:red; font-weight:bold; font-size:20px}
	.a3{color:blue; font-size:20px}
</style>

classList

En mer fleksibel løsning er å bruke classList. Vi vet at vi kan liste flere klassenavnmed blank mellom. I HTML5 kan vi betrakte denne lista som classList og vi kan manipulere innholdet i lista.

// add or remove a class name
elt.classList.add("hilited");
elt.classList.remove("hidden");

// add more than one
elt.classList.add("hilited","fixed"); 

// remove or add
elt.classList.toggle("hilited");

// is it in the list
if(elt.classList.contains("hilited"))
	alert("yes");
Dra musa over så blir det grønt.
<div id="target21" 
     class="basic" 
     onmouseover="changeClassItem(this,'showMeAsGreen','showMeAsBlue')" 
     onmouseout="changeClassItem(this,'showMeAsBlue','showMeAsGreen')">
    Dra musa over så blir det grønt.
</div>

Javascriptfunksjonen er slik:

function changeClassItem(elt,clsOn,clsOff)
{
    elt.classList.add(clsOn);
    elt.classList.remove(clsOff);
}

og stilsettet er slik.

<style id="mystyles2" type="text/css">
	.showMeAsGreen{color:green;}
	.showMeAsBlue{color:blue;}
	.basic{font-size:20px;font-weight:bold; }
</style>

Endre stilsett

Det er mulig å endre hvilket stilsett en HTML-side benytter fra JavaScript. Vi kan skru stilsett av og på med disabled

Dra musa over så blir det rødt.
<div id="target5" 
     class="hiliteMe" 
     onmouseover="changeStyleSheet('mystyles52','mystyles51')" 
     onmouseout="changeStyleSheet('mystyles51','mystyles52')">
    Dra musa over så blir det rødt.
    <!--initialize-->
    <script>changeStyleSheet('mystyles51','mystyles52')</script>
</div>

Javascriptfunksjonen er slik:

function changeStyleSheet(sheetIdOn,sheetIdOff){
    var eltOn=document.getElementById(sheetIdOn);
    var eltOff=document.getElementById(sheetIdOff);
    try{
        eltOn.disabled=false;
        eltOff.disabled=true;
    }
    catch(e){
        console.log(sheetIdOn,sheetIdOff, "not stylesheets ?");
    }
}

og stilsettene er slik.

<style id="mystyles51" type="text/css">
	.hiliteMe{color:blue; font-size:20px}
</style>

<style id="mystyles52" type="text/css">
	.hiliteMe{color:red;font-size:20px}
</style>
[1]
Referanser
  1. CSS (Cascading Style Sheets) W3C www.w3.org/TR/CSS/ 08-03-2014