Než se ponoÅÃme do způsobu, jakým JavaScript pracuje se styly a tÅÃdami, uvedeme důležité pravidlo. Doufáme, že je dostateÄnÄ známé, ale pÅesto je musÃme uvést.
Existujà v zásadÄ dva způsoby, jak nastavit styl elementu:
- VytvoÅit tÅÃdu v CSS a pÅiÅadit ji elementu:
<div class="..."> - Zapsat vlastnosti pÅÃmo do atributu
style:<div style="...">.
JavaScript umà modifikovat jak tÅÃdy, tak vlastnosti style.
Vždy bychom mÄli dávat pÅednost CSS tÅÃdám pÅed atributem style. Ten bychom mÄli použÃvat jen v pÅÃpadech, kdy to tÅÃdy ânezvládnouâ.
NapÅÃklad style je pÅijatelný, pokud dynamicky spoÄÃtáme souÅadnice elementu a chceme je nastavit z JavaScriptu, napÅÃklad takto:
let shora = /* složité výpoÄty */;
let zleva = /* složité výpoÄty */;
elem.style.left = zleva; // napÅ. '123px', vypoÄteno za bÄhu
elem.style.top = shora; // napÅ. '456px'
V jiných pÅÃpadech, napÅÃklad pro obarvenà textu ÄervenÄ nebo pÅidánà ikony na pozadÃ, popiÅ¡te vÅ¡e v CSS a pak pÅidejte tÅÃdu (JavaScript to umÃ). Je to flexibilnÄjšà a podpora je snadnÄjÅ¡Ã.
className a classList
ZmÄna tÅÃdy je jednou z nejÄastÄji použÃvaných akcà ve skriptech.
V dÅÃvÄjÅ¡Ãch dobách platilo v JavaScriptu omezenÃ: rezervované slovo, napÅ. "class", nemůže být vlastnostà objektu. Toto omezenà již neexistuje, ale v oné dobÄ nebylo možné mÃt vlastnost s názvem "class", napÅ. elem.class.
Pro tÅÃdy tedy byla zavedena podobná vlastnost "className": elem.className odpovÃdá atributu "class".
PÅÃklad:
<body class="hlavnà strana">
<script>
alert(document.body.className); // hlavnà strana
</script>
</body>
Jestliže do elem.className nÄco pÅiÅadÃme, nahradÃme tÃm celý ÅetÄzec tÅÃd. NÄkdy je to právÄ to, co potÅebujeme, ale Äasto chceme pÅidat nebo odebrat jedinou tÅÃdu.
K tomu sloužà jiná vlastnost: elem.classList.
elem.classList je speciálnà objekt s metodami add/remove/toggle pro pÅidánÃ, odstranÄnà a pÅepnutà jediné tÅÃdy.
PÅÃklad:
<body class="hlavnà strana">
<script>
// pÅidáme tÅÃdu
document.body.classList.add('Älánek');
alert(document.body.className); // hlavnà strana Älánek
</script>
</body>
Můžeme tedy pracovat jak s celým ÅetÄzcem tÅÃd pomocà className, tak s jednotlivými tÅÃdami pomocà classList. Záležà na naÅ¡ich potÅebách, co si vybereme.
Metody objektu classList:
elem.classList.add/remove("tÅÃda")â pÅidá/odstranà tÅÃdu.elem.classList.toggle("tÅÃda")â pokud tÅÃda nenà v seznamu, pÅidá ji, jinak ji odstranÃ.elem.classList.contains("tÅÃda")â ovÄÅÃ, zda zadaná tÅÃda je v seznamu, vrátÃtrue/false.
KromÄ toho classList je iterovatelný, takže si můžeme vypsat vÅ¡echny tÅÃdy cyklem for..of, napÅÃklad:
<body class="hlavnà strana">
<script>
for (let název of document.body.classList) {
alert(název); // hlavnÃ, pak strana
}
</script>
</body>
Styl elementu
Vlastnost elem.style je objekt, který odpovÃdá tomu, co je zapsáno do atributu "style". Nastavenà elem.style.width="100px" funguje stejnÄ, jako kdybychom mÄli v atributu style ÅetÄzec width:100px.
U vÃceslovných vlastnostà se použÃvá velbloudÃNotace:
background-color => elem.style.backgroundColor
z-index => elem.style.zIndex
border-left-width => elem.style.borderLeftWidth
PÅÃklad:
document.body.style.backgroundColor = prompt('barva pozadÃ?', 'green');
Stejné pravidlo dodržujà i vlastnosti s prefixem prohlÞeÄe, napÅ. -moz-border-radius, -webkit-border-radius: pomlÄka znamená velké pÃsmeno.
PÅÃklad:
button.style.MozBorderRadius = '5px';
button.style.WebkitBorderRadius = '5px';
Resetovánà vlastnosti style
NÄkdy chceme do vlastnosti style nÄco pÅiÅadit a pozdÄji to odstranit.
NapÅÃklad můžeme nastavit elem.style.display = "none", abychom skryli element.
PozdÄji můžeme chtÃt style.display odstranit, jako by vůbec nebyla nastavena. MÃsto mazánà delete elem.style.display bychom do nà mÄli pÅiÅadit prázdný ÅetÄzec: elem.style.display = "".
// spustÃme-li tento kód, <body> blikne
document.body.style.display = "none"; // schovat
setTimeout(() => document.body.style.display = "", 1000); // zpÄt do normálu
Jestliže nastavÃme style.display na prázdný ÅetÄzec, prohlÞeÄ aplikuje CSS tÅÃdy a jejich zabudované styly bÄžným způsobem, jako by vlastnost style.display vůbec neexistovala.
K tomu existuje i speciálnà metoda, elem.style.removeProperty('vlastnost stylu'). Můžeme tedy odstranit vlastnost následovnÄ:
document.body.style.background = 'red'; // nastavÃme Äervené pozadÃ
setTimeout(() => document.body.style.removeProperty('background'), 1000); // za 1 sekundu pozadà odstranÃme
style.cssTextK nastavenà jednotlivých vlastnostà stylu použÃváme bÄžnÄ style.*. Nemůžeme nastavit celý styl způsobem div.style="color: red; width: 100px", protože div.style je objekt a sloužà pouze pro ÄtenÃ.
K tomu, abychom nastavili celý styl jednÃm ÅetÄzcem, existuje speciálnà vlastnost style.cssText:
<div id="div">TlaÄÃtko</div>
<script>
// zde můžeme nastavit speciálnà pÅepÃnaÄe stylu, napÅ. "important"
div.style.cssText=`color: red !important;
background-color: yellow;
width: 100px;
text-align: center;
`;
alert(div.style.cssText);
</script>
Tato vlastnost se použÃvá jen zÅÃdka, neboÅ¥ takové pÅiÅazenà odstranà vÅ¡echny existujÃcà styly: nepÅidává nové styly, ale nahrazuje existujÃcÃ. ObÄas může smazat nÄco, co potÅebujeme. Můžeme ji vÅ¡ak bezpeÄnÄ použÃvat pro nové elementy, u nichž vÃme, že jim nesmažeme existujÃcà styl.
Téhož můžeme dosáhnout nastavenÃm atributu: div.setAttribute('style', 'color: red...').
NezapomÃnejte na jednotky
NezapomÃnejte pÅidávat k hodnotám CSS jednotky.
NapÅÃklad elem.style.top bychom nemÄli nastavovat na 10, ale na 10px. Jinak to nebude fungovat:
<body>
<script>
// nefunguje to!
document.body.style.margin = 20;
alert(document.body.style.margin); // '' (prázdný ÅetÄzec, pÅiÅazenà je ignorováno)
// nynà pÅidáme CSS jednotku (px) - a už to funguje
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>
ProsÃme vÅ¡imnÄte si, že na poslednÃch ÅádcÃch prohlÞeÄ ârozbalÃâ vlastnost style.margin a odvodà z nà style.marginLeft a style.marginTop.
VypoÄÃtané vlastnosti: getComputedStyle
ZmÄnit styl je tedy jednoduché. Ale jak jej naÄÃst?
Chceme napÅÃklad znát velikost, okraje nebo barvu elementu. Jak to udÄlat?
Vlastnost style pracuje jen s hodnotou atributu "style" bez jakékoli CSS kaskády.
Pomocà elem.style tedy nejsme schopni naÄÃst nic, co pocházà z CSS tÅÃd.
NapÅÃklad zde style nevidà vnÄjšà okraj (margin):
<head>
<style> body { color: red; margin: 5px } </style>
</head>
<body>
Äervený text
<script>
alert(document.body.style.color); // prázdný
alert(document.body.style.marginTop); // prázdný
</script>
</body>
â¦Ale co když chceme tÅeba zvÄtÅ¡it vnÄjšà okraj o 20px? ChtÄli bychom znát jeho aktuálnà hodnotu.
K tomu sloužà jiná metoda: getComputedStyle.
Jejà syntaxe je:
getComputedStyle(element, [pseudo])
- element
- Element, jehož hodnota má být naÄtena.
- pseudo
- Pseudoelement, pokud je vyžadován, napÅÃklad
::before. Prázdný ÅetÄzec nebo žádný argument znamená samotný element.
Výsledkem je objekt obsahujÃcà styly, podobný elem.style, ale tentokrát s ohledem na vÅ¡echny CSS tÅÃdy.
NapÅÃklad:
<head>
<style> body { color: red; margin: 5px } </style>
</head>
<body>
<script>
let vypoÄÃtanýStyl = getComputedStyle(document.body);
// nynà z nÄj můžeme naÄÃst vnÄjšà okraj a barvu
alert( vypoÄÃtanýStyl.marginTop ); // 5px
alert( vypoÄÃtanýStyl.color ); // rgb(255, 0, 0)
</script>
</body>
V CSS jsou dva koncepty:
- VypoÄÃtaná (computed) hodnota stylu je hodnota zÃskaná po aplikaci vÅ¡ech CSS pravidel a CSS dÄdiÄnosti, tedy výsledek CSS kaskády. Může vypadat jako
height:1emnebofont-size:125%. - Vyhodnocená (resolved) hodnota stylu je ta, která se nakonec aplikuje na element. Hodnoty jako
1emnebo125%jsou relativnÃ. ProhlÞeÄ vezme vypoÄÃtanou hodnotu a zmÄnà vÅ¡echny jednotky na pevné a absolutnÃ, napÅÃkladheight:20pxnebofont-size:16px. Vyhodnocené hodnoty geometrických vlastnostà mohou mÃt pohyblivou Äárku, napÅÃkladwidth:50.5px.
Metoda getComputedStyle vznikla pÅed dlouhou dobou, aby vracela vypoÄÃtané hodnoty, ale ukázalo se, že vyhodnocené hodnoty jsou mnohem vhodnÄjÅ¡Ã, a tak se standard zmÄnil.
V souÄasnosti tedy getComputedStyle ve skuteÄnosti vracà vyhodnocenou hodnotu vlastnosti, pro geometrii obvykle v px.
getComputedStyle vyžaduje celý název vlastnostiVždy bychom se mÄli ptát na pÅesnou vlastnost, kterou chceme znát, napÅÃklad paddingLeft, marginTop nebo borderTopWidth. Jinak nemáme zaruÄen správný výsledek.
NapÅÃklad pokud existujà vlastnosti paddingLeft/paddingTop, co bychom pak mÄli obdržet pro getComputedStyle(elem).padding? Nic, nebo snad âvygenerovanouâ hodnotu ze známých vnitÅnÃch okrajů (paddingů)? Žádné standardnà pravidlo zde neexistuje.
:visited jsou skryté!NavÅ¡tÃvené odkazy mohou být obarveny pomocà CSS pseudotÅÃdy :visited.
Ale getComputedStyle pÅÃstup k této barvÄ neposkytuje, neboÅ¥ jinak by libovolná stránka mohla zjistit, zda uživatel navÅ¡tÃvil nÄjaký odkaz, tak, že si ho vytvoÅà a zjistà jeho styly.
JavaScript nesmà vidÄt styly aplikované pomocà :visited. RovnÄž CSS obsahuje omezenÃ, které zakazuje ve :visited aplikovat styly mÄnÃcà geometrii. TÃm je zaruÄeno, že neexistuje žádný vedlejšà způsob, jak by zlá stránka mohla zjistit, zda byl nÄjaký odkaz navÅ¡tÃven, a tÃm poruÅ¡it soukromÃ.
ShrnutÃ
Ke správÄ tÅÃd sloužà dvÄ vlastnosti DOMu:
classNameâ ÅetÄzcová hodnota, hodà se pro správu celé sady tÅÃd.classListâ objekt s metodamiadd/remove/toggle/contains, hodà se pro jednotlivé tÅÃdy.
Ke zmÄnÄ stylu:
-
Vlastnost
styleje objekt, který obsahuje styly zapsané velbloudÃNotacÃ. Ätenà a zápis do nÄj má stejný význam jako modifikace jednotlivých vlastnostà v atributu"style". Chcete-li vidÄt, jak se aplikujeimportanta jiné vzácnÄ použÃvané vlastnosti, MDN obsahuje seznam metod. -
Vlastnost
style.cssTextodpovÃdá celému atributu"style", úplnému ÅetÄzci stylů.
K naÄtenà vyhodnocených stylů (s ohledem na vÅ¡echny tÅÃdy po aplikaci vÅ¡ech CSS a výpoÄtu finálnÃch hodnot):
- Metoda
getComputedStyle(elem, [pseudo])vracà objekt podobný stylu, který je obsahuje. Je pouze pro ÄtenÃ.
KomentáÅe
<code>, pro nÄkolik Åádků je obalte znaÄkou<pre>, pro vÃce než 10 Åádků vložte odkaz na pÃskoviÅ¡tÄ (plnkr, jsbin, codepenâ¦)