DOM - Objektový model dokumentu 10.

Dnes se budeme zabývat manipulací s CSS stylesheety. Naučíme se mimo jiné přidávat, měnit či mazat jednotlivá pravidla či deklarace.
V minulém dílu jsme si ukázali práci se stylem jednotlivého elementu ("inline" stylem) skrz rozhraní DOM a poté jsme se začali zabývat manipulací se stylesheety (tabulkami kaskádových stylů). Představili jsme si kolekci document.styleSheets, vypínání a zapínání stylesheetu pomocí vlastnosti disabled a další také pár dalších vlastnosti objektu typu styleSheet (včetně odlišností mezi IE a Mozillou).

Dnes si ukážeme všechny zbývající metody a vlastnosti, které nám umožní "operovat" se stylesheety. Na začátku by možná bylo vhodné připomenout, z jakých částí se stylesheet kaskádového stylu skládá a jak je připojen do dokumentu - DOM objektové rozhraní samozřejmě vychází z této struktury.

Krátký přehled struktury CSS

Kaskádový styl lze k HTML dokumentu připojit pomocí elementu <style> nebo elementu <link>. Obsahem elementu <style> bývá vlastní seznam css pravidel (stylesheet je tedy přímo součástí dokumentu):

<style type="text/css">
  p {
    font-size: 15px;
    text-align: right;
  }
  h1, h2, h3 {
    margin: 10px;
    color: red;
  }
</style>

Element <style> (přesněji řečeno i jakýkoliv css stylesheet) může dle normy CSS 2 obsahovat i direktivu @url import, díky které lze připojit (vložit) další externí stylesheet:

<style type="text/css">
  @import url("muj_stylesheet.css");
</style>

Pomocí elementu <link> lze připojit k dokumentu externí stylesheet:

<link rel="stylesheet" type="text/css" href="css3.css" />

Každému elementu <style> nebo <link> odpovídá jedna položka v kolekci stylesheetů získaná pomocí document.styleSheets přesně v pořadí, jak jsou tyto stylesheety uvedeny v dokumentu. Pokud bychom tedy v HTML dokumentu měli za sebou všechny tři výše uvedené deklarace, kolekce styleSheets by obsahovala 3 prvky. Pozor na direktivu @url import - objekt typu styleSheet odkazuje na obsah elementu <style> nebo <link>, pokud tedy bude v jednom elementu <style> více importovaných stylesheetů, všechny tyto importované stylesheety dohromady tvoří v rámci DOM jeden jediný stylesheet!

Stylesheet je tvořen souborem pravidel (rules). Pravidlo vypadá například takto:

  p {
    font-size: 15px;
    text-align: right;
  }

Každé pravidlo se skládá ze selektoru a z jedné nebo více deklarací. Selektor určuje, na které elementy (třídy, id, atd.) se dané pravidlo vztahuje. Deklarace se skládá z vlastnosti a její hodnoty.

V naší ukázce výše je selektorem p, nebo h1, h2, h3.

Deklarace je např.

font-size: 15px;

přičemž font-size je vlastnost a 15px je její hodnota.

Manipulace s pravidly v CSS stylesheetu

Ke kolekci všech pravidel ve jednom stylesheetu získáme přístup pomocí vlastnosti cssRules.

var pravidla = document.styleSheets[2].cssRules;

Bohužel jen v Mozille, této standardní vlastnosti Internet Explorer nerozumí. Microsoft má pro tuto vlastnost jiný název rules.

var pravidla = document.styleSheets[2].rules;

Pokud chceme zajistit cross-browser kompatibilitu, nevyhneme se tedy "vidličkám".

var sheet = document.styleSheets[2];
var pravidla;
(sheet.rules) ? pravidla = sheet.rules : pravidla = sheet.cssRules;

Přidání pravidla

Do stylesheetu je možné přidat další pravidlo pomocí metody insertRule(). Jako první parametr se předává celé pravidlo a jako druhý parametr je předáván index vkládaného pravidla.

sheet.insertRule("p { font-weight: bold; padding-left: 20px;}", 2);

V Internet Exploreru je syntaxe bohužel znovu odlišná. Metoda nese název addRule() a má i mírně odlišnou syntaxi. Jako první parametr je nutné udat selektor, jako druhý parametr následuje seznam deklarací a jako třetí parametr index.

sheet.addRule("p", "font-weight: bold; padding-left: 20px;", 2);

Opět nám tedy nezbývá než udělat podmínkovou konstrukci:

if(sheet.addRule) {
sheet.addRule("p", "font-weight: bold; padding-left: 20px;", 2);
} else if(sheet.insertRule) {
sheet.insertRule("p { font-weight: bold; padding-left: 20px;}", 2);
}

Podívejte se na příklad vytváření pravidel stylesheetu pomocí DOM.

Odstranění pravidla

Odstranění pravidla ze stylesheetu zajišťuje metoda deleteRule(). Jako jediný parametr se uvádí index pravidla, které chceme odstranit. Např. odstranění třetího pravidla, které jsme do stylesheetu přidali pomocí DOM v příkladu syntaxe metody insertRule, by vypadalo takto:

sheet.deleteRule(2);

Microsoft se dle W3C normy stále nechová a opět musíme použít proprietální metodu removeRule(). Jinak je práce této metody zcela identická s deleteRule().

sheet.removeRule(2);

Obligátní "ošetřující" konstrukce bude tedy vypadat zhruba takto:

if (sheet.removeRule) {
sheet.removeRule(2);
} else if(sheet.deleteRule) {
sheet.deleteRule(2);
}

Pozor na složené selektory - například toto pravidlo ve stylesheetu:

h1, h2, h3 {
    margin: 10px;
    color: red;
  }

je v DOM interpretováno jako tři samostatná pravidla, chová se tedy tak, jako kdyby syntaxe byla takováto:

h1 {
    margin: 10px;
    color: red;
  }
h2 {
    margin: 10px;
    color: red;
  }
h3 {
    margin: 10px;
    color: red;
  }

Prakticky to tedy znamená, že v tomto stylesheetu:

<style type="text/css">
  p {
    font-size: 15px;
    text-align: right;
  }
  h1, h2, h3 {
    margin: 10px;
    color: red;
  }
</style>

jsou 4 pravidla, z nichž každé lze odstranit (i jinak s ním manipulovat) samostatně.

Manipulace s obsahem CSS pravidla

Podobně, jako když měníme styl jednotlivého elementu ("inline" styl) přes objekt stylu (viz minulý díl), můžeme stejným způsobem přistupovat i k jednotlivému pravidlu stylesheetu. Vlastnost style vrací objekt stylu, charakterizovaný dalšími vlastnostmi, díky kterým je možné získávat i měnit hodnoty css vlastností.

var pravidlo = document.styleSheets[2].cssRules[3]; // v IE nutno použít rules, viz výše…
var bg_color = pravidlo.style.backgroundColor; //získání
pravidlo.style.backgroundColor="yellow"; //nastavení

Syntaxe a použití všech vlastností objektu style je zcela ve shodě s popisem objektu style u "inline-stylu" v minulém dílu.

V Mozille lze získat určitou CSS vlastnost pravidla pomocí metod getPropertyValue(). Metoda getPropertyValue() se aplikuje na objekt stylu a jako jediný parametr je předáváno jméno CSS vlastnosti.

pravidlo.style.getPropertyValue(`color`);

Na objekt stylu je možné použit vlastnost cssText. Tato vlastnost vrací seznam všech deklarací daného pravidla jako textový řetězec.Je možné ji použít i pro nastavení deklarací.

var seznam_deklarací = pravidlo.style.cssText; // získání seznamu deklarací
pravidlo.style.cssText="font-size: 13px; text-decoration: underline"; // nastavení deklarací

V Mozille lze vlastnost cssText použít i na objekt pravidla přímo, bez objektu stylu. V tomto případě bude výsledkem text celého pravidla včetně selektoru.

var text_pravidla = pravidlo.cssText; // pouze v Mozille! 

Výše uvedená syntaxe vrátí kupříkladu:

  p { font-size: 15px; text-align: right;}

V tomto případě je vlastnost "read-only", pouze pro čtení, nelze tedy nastavit text celého pravidla. Další vlastností, kterou lze použít ve spojením s objektem pravidla, je selectorText. Vrací selektor daného pravidla, např "p".

var selektor = pravidlo.selectorText;

Nezapomeňme, že pravidla se složenými selektory jsou v DOM rozděleny do odpovídajícího počtu samostatných pravidel, takže např. vrácení hodnoty "h1, h2, h3" nelze od této vlastnosti očekávat.

Další vlastnosti

Další vlastností objektu pravidla je parentStyleSheet. Vrací objekt stylesheetu, který obsahuje dané pravidlo. Vlastnost lze využít nejen u pravidla, ale i u "vnořeného" stylesheetu (importovaného do jiného stylesheetu pomocí direktivy @url import). Pokud je tento stylesheet součástí jiného stylesheetu, je vrácen objekt "rodičovského" stylesheetu, jinak vrací null.

var rodic_sheet = pravidlo.parentStyleSheet; // použití s objektem pravidla
var rodic_sheet = stylesheet.parentStyleSheet;// použití s objektem stylesheetu

V DOM lze také využít vlastnost, která vrací element, jenž "nese" příslušný stylesheet, tedy určitý element <link> nebo <style>. Tato vlastnost má název ownerNode a lze ji použít ve spojení s objektem stylesheetu.

var ss_element = stylesheet.ownerNode; // pouze v Mozille

V Internet Exploreru má tato vlastnost opět odlišný název, a to owningElement.

var ss_element = stylesheet.owningElement; // pouze IE

Další, pouze v Mozille dostupná vlastnost objektu stylesheet, je ownerRule. Pokud je stylesheet importován direktivou @url import, vlastnost vrací objekt pravidla "rodičovského" stylesheetu, které obsahuje tuto direktivu.

Vytvoření nového stylesheetu

Nakonec si ukážeme, jak můžeme vytvořit nový stylesheet a přidat jej do dokumentu. V tomto bodě si reputaci spraví Internet Explorer, neboť na rozdíl od Mozilly umožňuje vytvořit a přidat nový stylesheet, a to hned dvěma způsoby. První způsob využívá proprietální metodu createStyleSheet(). Metoda má 2 parametry, prvním je URL souboru stylesheetu a druhým je index (pokud není explicitně uveden, stylesheet je přidám na konec stávající kolekce stylesheetů).

var novy_sheet = document.createStyleSheet("mujstyl2.css");

Tato metoda vrací objekt nově vytvořeného stylesheetu, se kterým lze dále manipulovat obvyklými prostředky.

Druhý způsob, který by teoreticky měl fungovat i v Mozille, ale díky bugu v ní nefunguje, je přes vytvoření objektu elementu, který stylesheet ponese:

var novy_sheet = document.createElement("style"); // nebo "link"
novy_sheet.setAttribute("type", "text/css"); // v pripade elementu link jeste "rel" a "href"
document.head.appendChild(novy_sheet);

A poté pomocí metody addRule() lze přidávat jednotlivá pravidla. Bohužel Mozilla ignoruje nově přidaný objekt elementu, který ponese stylesheet a tak zatím neznám cestu, jak Mozillu přimět k přidání nového stylesheetu do dokumentu. V Konqueroru údajně funguje standardní DOM Level2 Style metoda createCSSStyleSheet(), zřejmě si tedy budeme muset počkat, až bude možné tuto metodu využívat i v Mozille.

Tím jsme prakticky využitelnou část DOM pro práci se styly v podstatě vyčerpali. Norma W3C DOM Level 2 Style sice definuje ještě další rozhraní, metody a vlastnosti, nicméně jejich podpora je buď nulová, anebo je velmi sporá či chybná.

Nyní tedy přichází na řadu slíbená přehledná tabulka.

Tabulka metod a vlastností pro práci se stylesheety a CSS

vlastnost nebo metoda: součást DOM: IE 5, 5.5 IE 6 Mozilla/NN6 Konqueror 2.2 Opera 5, 6 poznámky
vlastnosti objektu Document
styleSheets[] L2 StyleSheets ANO ANO ANO NE NE  
vlastnosti objektu styleSheet
disabled L2 StyleSheets ANO ANO ANO NE NE i nastavení
type L2 StyleSheets ANO ANO ANO NE NE  
title L2 StyleSheets ANO ANO ANO NE NE i nastavení
href L2 StyleSheets ANO ANO ANO NE NE v IE i nastavení
parentStyleSheet L2 StyleSheets ANO ANO ANO NE NE  
cssRules[] L2 CSS NE NE ANO NE NE IE:rules[]
insertRule(pravidlo, index) L2 CSS NE NE ANO NE NE IE:addRule()
deleteRule(index) L2 CSS NE NE ANO ANO NE IE:removeRule()
ownerNode L2 StyleSheets NE NE ANO NE NE IE:owningElement
ownerRule L2 CSS NE NE ANO NE NE  
media L2 StyleSheets chybně chybně ANO NE NE v IE i nastavení
vlastnosti objektu cssRule
style L2 CSS ANO ANO ANO NE NE  
selectorText L2 CSS ANO ANO ANO NE NE  
cssText L2 CSS ANO ANO ANO NE NE i nastavení
parentStyleSheet L2 CSS ANO ANO ANO NE NE  
getPropertyValue(jméno) L2 CSS NE NE ANO NE NE  
vlastnosti a metody objektu typu MediaList
length L2 CSS NE NE ANO NE NE  
mediaText L2 CSS NE NE ANO NE NE i nastavení
appendMedium(jméno) L2 CSS NE NE ANO NE NE  
deleteMedium(jméno) L2 CSS NE NE ANO NE NE  
Nestandardní metody a vlastnosti od Microsoftu
rules[] MS ANO ANO NE NE NE  
addRule(selektor, deklarace, index) MS ANO ANO NE NE NE  
removeRule(index) MS ANO ANO NE NE NE  
owningElement MS ANO ANO NE NE NE  
createStyleSheet(URL, index) MS ANO ANO NE NE NE  
Diskuze (1) Další článek: Apache 2.0 je oficiálně k dispozici

Témata článku: , , , , , , , , , , , , , , , , , , , , , , , , ,