Fr vi dykkter ned i JavaScripts mde at arbejde med styles og classes er der en vigtig regel. Forhbentligt er den tydelig i eksemplerne, men vi br nok stadig nvne den fra starten.
Der er generelt to mder at style et element:
- Opret en klasse i CSS og tilfj den:
<div class="..."> - Skriv egenskaber direkte ind i
style:<div style="...">.
JavaScript kan bde ndre bde classes og style egenskaber.
Vi br altid foretrkke CSS-classes frem for style. Den sidste br kun bruges, hvis classes ikke kan klare det.
For eksempel er style acceptabel, hvis vi beregner koordinater for et element dynamisk og vil stte dem fra JavaScript, sdan her:
let top = /* kompleks beregning */;
let left = /* kompleks beregning */;
elem.style.left = left; // e.g '123px', beregnes ved krsel
elem.style.top = top; // e.g '456px'
I andre situationer, som at gre teksten rd, tilfje et baggrundsbillede beskriv det i CSS og tilfj derefter klassen (det kan JavaScript gre). Det er mere fleksibelt og lettere at vedligeholde.
className og classList
ndring af class er en af de mest brugte handlinger i scripts.
I gamle dage var der en begrnsning i JavaScript: et reserveret ord som "class" kunne ikke vre en egenskab for et objekt. Denne begrnsning findes ikke lngere, men p det tidspunkt var det umuligt at have en "class"-egenskab, som elem.class.
S for classes blev den lignende egenskab "className" introduceret: the elem.className corresponds to the "class" attribute.
For eksempel:
<body class="main page">
<script>
alert(document.body.className); // main page
</script>
</body>
Hvis vi tildeler noget til elem.className, erstatter det hele strengen af classes. Nogle gange er det det vi har brug for, men ofte vil vi kun tilfje/fjerne en enkelt class.
Der er en anden egenskab for det: elem.classList.
Objektet elem.classList er et specielt objekt med metoderne add/remove/toggle i relation til en enkelt class.
For eksempel:
<body class="main page">
<script>
// tilfj en class
document.body.classList.add('article');
alert(document.body.className); // main page article
</script>
</body>
S vi kan bde behandle hele strengen af classes ved hjlp af className eller individuelle classes ved hjlp af classList. Hvad vi vlger, afhnger af vores behov.
Metoder for classList:
elem.classList.add/remove("class")tilfjer/fjerner en class.elem.classList.toggle("class")tilfjer classen, hvis den ikke eksisterer, ellers fjerner den.elem.classList.contains("class")tjekker for den givne class, returnerertrue/false.
Derudover er classList itererbar, s vi kan opliste alle classes med for..of, sdan her:
<body class="main page">
<script>
for (let name of document.body.classList) {
alert(name); // main, og derefter page
}
</script>
</body>
Element style
Egenskaben elem.style er et objekt, der svarer til det, der er skrevet i "style"-attributten. At stte elem.style.width="100px" virker p samme mde som hvis vi havde strengen width:100px sat i attributten style.
For egenskaber sammensat af flere ord bruges camelCase i stedet for bindestreger. Det betyder, at bindestreger i CSS erstattes af store bogstaver i JavaScript.:
background-color => elem.style.backgroundColor
z-index => elem.style.zIndex
border-left-width => elem.style.borderLeftWidth
For eksempel:
document.body.style.backgroundColor = prompt('background color?', 'green');
Browser-prfiks egenskaber som -moz-border-radius, -webkit-border-radius flger ogs samme regle: en bindestreg betyder stort bogstav.
For eksempel:
button.style.MozBorderRadius = '5px';
button.style.WebkitBorderRadius = '5px';
Nulstilling af en style egenskab
Nogle gange vil vi tildele en vrdi til en style egenskab, andre gange vil vi fjerne den.
For eksempel, for at skjule et element, kan vi stte elem.style.display = "none".
Senere vil vi mske nske at fjerne vrdien fra style.display som om den ikke var sat. I stedet for delete elem.style.display br vi tildele en tom streng til den: elem.style.display = "".
// hvis vi krer denne kode, vil <body> blinke
document.body.style.display = "none"; // hide
setTimeout(() => document.body.style.display = "", 1000); // tilbage til normal
Hvis vi stter style.display til en tom streng, s anvender browseren egne indbyggede CSS-klasser og stil, som om der ikke var nogen sdan style.display-egenskab overhovedet.
Der er ogs en speciel metode til det, elem.style.removeProperty('style property'). S kan vi fjerne en egenskab sdan her:
document.body.style.background = 'red'; //st background til red
setTimeout(() => document.body.style.removeProperty('background'), 1000); // fjern background efter 1 sekund
style.cssTextNormalt bruger vi style.* til at tildele individuelle style-egenskaber. Vi kan ikke stte et samlet udseende (flere enkelte styles) i stil med div.style="color: red; width: 100px", fordi div.style er et objekt, og det er read-only.
For at stte den samlede style som en enkelt streng, er der en speciel egenskab style.cssText:
<div id="div">Knap</div>
<script>
// vi kan stte specielle style flag som "important" her
div.style.cssText=`color: red !important;
background-color: yellow;
width: 100px;
text-align: center;
`;
alert(div.style.cssText);
</script>
Denne egenskab er sjldent brugt, fordi en sdan tildeling fjerner alle eksisterende styles: det tilfjer ikke, men erstatter dem. Det kan betyde, at du kommer til at slette noget, der er ndvendigt. Men vi kan trygt bruge den for nye elementer, nr vi ved, at vi ikke vil slette en eksisterende style.
Det samme kan opns ved at stte en attribut: div.setAttribute('style', 'color: red...').
Vr opmrksom p enheder
Glem ikke at tilfje CSS-enheder til vrdier.
For eksempel skal vi ikke stte elem.style.top til 10, men til 10px ellers virker det ikke:
<body>
<script>
// virker ikke!
document.body.style.margin = 20;
alert(document.body.style.margin); // '' (tom streng, tildeling ignoreres)
// tilfj nu en CSS-enhed (px) - og s virker det
document.body.style.margin = '20px';
alert(document.body.style.margin); // 20px
alert(document.body.style.marginTop); // 20px
alert(document.body.style.marginLeft); // 20px
</script>
</body>
Bemrk: browseren pakker egenskaber ud s egenskaben style.margin i forrige eksempel afleder selv vrdierne i style.marginLeft og style.marginTop fra style.margin.
beregnet udseende: getComputedStyle
S det, at modificere en style er ret nemt. Men hvordan lser man det?
Hvis vi f.eks. vil vide strrelsen, margenerne og farven p et element. Hvordan gr vi det?
Egenskaben style opererer kun med vrdien af "style" attributten uden CSS cascade.
Derfor kan vi ikke lse noget, der kommer fra CSS-klasser ved hjlp af elem.style.
For eksempel ser style ikke marginen, der er defineret i CSS:
<head>
<style> body { color: red; margin: 5px } </style>
</head>
<body>
The red text
<script>
alert(document.body.style.color); // empty
alert(document.body.style.marginTop); // empty
</script>
</body>
men hvad nu hvis vi f.eks. vil ge marginen med 20px? Til det har vi brug for at vide den nuvrende vrdi.
Der findes en metode til det: getComputedStyle.
Syntaksen er:
getComputedStyle(element, [pseudo])
- element
- Det element du vil lse vrdien for.
- pseudo
- Et pseudo-element hvis krvet, for eksempel
::before. En tom streng eller intet argument betyder selve elementet.
Resultatet er et objekt med styles, som du kender dem fra elem.style, men nu med hensyn til alle CSS-klasser.
For eksempel:
<head>
<style> body { color: red; margin: 5px } </style>
</head>
<body>
<script>
let computedStyle = getComputedStyle(document.body);
// nu kan vi lse marginen og farven fra det
alert( computedStyle.marginTop ); // 5px
alert( computedStyle.color ); // rgb(255, 0, 0)
</script>
</body>
Der er to koncepter i CSS:
- En computed style-vrdi er vrdien efter alle CSS-regler og CSS-arv er anvendt, som resultatet af CSS-kaskaden. Den kan se ud som
height:1emellerfont-size:125%. - En resolved style-vrdi er den vrdi, der endelig er anvendt p elementet. Vrdier som
1emeller125%er relative. Browseren tager den computed vrdi og gr alle enheder faste og absolute, for eksempel:height:20pxellerfont-size:16px. For geometriske egenskaber kan resolved vrdier have et flydende komma, somwidth:50.5px.
For lang tid siden blev getComputedStyle oprettet for at hente computed vrdier, men det viste sig, at de endeligt udledte vrdier er meget mere praktiske, og standarden ndrede sig.
S nu om stunder returnerer getComputedStyle faktisk de udledte vrdier, normalt i px for geometriske egenskaber.
getComputedStyle krver det fulde navn p egenskabenVi br altid sprge efter den prcise egenskab, vi vil have, som paddingLeft eller marginTop eller borderTopWidth. Ellers er det ikke garanteret, at vi fr det korrekte resultat.
For eksempel, hvis der er sat egenskaber for paddingLeft/paddingTop, hvad skal vi f for getComputedStyle(elem).padding? Intet, eller mske en genereret vrdi fra kendte padding-vrdier? Der er ingen standardregel her.
:visited links er skjulte!Besgte links kan farves ved hjlp af CSS-pseudoklassen :visited.
Men getComputedStyle giver ikke adgang til den farve, fordi ellers kunne en vilkrlig side finde ud af, om brugeren har besgt en link ved at oprette den p siden og tjekke stilene.
JavaScript kan ikke se de stilarter, der er anvendt af :visited. Der er ogs en begrnsning i CSS, der forbyder at anvende ndringer relateret til geometri i :visited. Det er for at garantere, at der ikke er nogen smutveje for en ond side til at teste, om en link blev besgt og dermed bryde med regler for privatliv.
Opsummering
Til at hndtere klasser, er der to DOM-egenskaber:
classNameen regulr streng, god til at hndtere hele sttet af klasser.classListet objekt med metoderadd/remove/toggle/contains, god til individuelle klasser.
For at ndre stilene:
-
Egenskaben
styleer et objekt med camelCased styles. Lsning og skrivning til dem har samme betydning som at modificere de individuelle egenskaber i"style"-attributten. For at se, hvordan man anvenderimportantog andre mindre brugte muligheder er der en liste af metoder p MDN. -
Egenskaben
style.cssTextsvarer til hele"style"-attributten alts, den fulde streng af styles.
For at lse de udledte styles (resolved values) (hvor der tages hensyn til alle klasser, og efter at al CSS er anvendt og de endelige vrdier er beregnet):
getComputedStyle(elem, [pseudo])returnerer et style-lignende objekt med dem. Skrivebeskyttet.
Kommentarer
<code>-taggen, for flere linjer - omslut dem i<pre>-tag, for mere end 10 linjer - brug en sandbox (plnkr, jsbin, codepen)