document.styleSheets, czyli bezpośredni dostęp do stylów z JS

Dostęp do stylów elementów poprzez JavaScript nikogo nie dziwi - w końcu sam DOM daje nam możliwości edytowania stylów dla poszczególnych elementów poprzez obiekt style. Dodatkowo metody takie jak getComputedStyle pozwalają nam na dostęp do aktualnych, "obliczonych" wartości przypisanych do elementów. Po co w takim razie bezpośredni dostęp do arkuszy stylów?



Sam dostęp do arkuszy pozwala nam na dostęp do domyślnych wartości stylu (a niekoniecznie wartości dla danego tagu, które mogły być nadpisane przez inne definicje). Jednak dużo bardziej przydatne podczas używania animacji CSS3, a zwłaszcza w kontekście podmiany ich wartości.

Ale od początku.
Obiekt document w wartości styleSheets przechowuje listę obiektów CSSStyleSheet. Każdy styleSheet odnosi się do kolejnego elementu <style>umieszczone na stronie. Niestety wyszukanie konkretnego stylu wymaga sprawdzenia wszystkich elementów umieszczonych w tych tablicach.

// przykładowy obiekt CSSStyleSheet
{0: //CSSStyleSheet
 {
   cssRules: CSSRuleList,
   disabled: false,
   href: "http://yui.yahooapis.com/3.3.0/build/cssreset/reset-min.css",
   media: MediaList,
   ownerNode: HTMLLinkElement,
   ownerRule: null,
   parentStyleSheet: null,
   rules: CSSRuleList,
   title: null,
   type: "text/css"
 }
}
Element styleSheet (obiekt, interfejs) zasadniczo posiada dostęp do wszystkich wartości, które zostały podane jako właściwości. Dodatkowo podsiada listę cssRules, która zawiera tablicę obiektów CSSRule. Obiekty CSSRule mogą być różnych typów i w zależności od tego możemy odwoływać się bezpośrednio do stylów.

TypWartość
UNKNOWN_RULE0
STYLE_RULE1
CHARSET_RULE2
IMPORT_RULE3
MEDIA_RULE4
FONT_FACE_RULE5
PAGE_RULE6
MOZ_KEYFRAMES_RULE (Firefox)7
MOZ_KEYFRAME_RULE (Firefox)8
WEBKIT_KEYFRAMES_RULE (Chrome)8
WEBKIT_KEYFRAME_RULE (Chrome)9
KEYFRAMES_RULE (Opera)7
KEYFRAME_RULE (Opera)8

Teraz zajmiemy się typami dotyczącymi stylów oraz animacji CSS3. W przypadku stylów sprawa jest już prosta. Pobierając element dostęp do poszczególnych właściwości mamy poprzez obiekt style lub metodę getPropertyValue tego obiektu. Ustawianie nowych wartości tak samo jak w DOMie czyli .style.marginTop lub poprzez setProperty.
// obiekt CSSRule
{
   cssText: "html, body, input { font-size: 12px; font-family: Arial; color: rgb(56, 56, 56); }"
   parentRule: null
   parentStyleSheet: CSSStyleSheet
   selectorText: "html, body, input"
   style: { // CSSStyleDeclaration
      0: "font-size"
      1: "font-family"
      2: "color"
      cssText: "font-size: 12px; font-family: Arial; color: rgb(56, 56, 56); "
      length: 3
      parentRule: CSSStyleRule
   }
   type: 1 // STYLE_RULE
}
Oprócz bezpośredniej modyfikacji stylów możemy także dodawać nowe style, a także je kasować. Do tego używamy metod insertRule oraz deleteRule. Czasami może się okazać, że będziemy zmuszeni do używania tych opcji (patrz część o Firefox).
Animacje CSS3 zawierają w sobie kilka definicji stylów (dla każdego z kroków), dlatego dostęp już do konkretnych wartości jest możliwy poprzez kolejną listę cssRules i dalej tak samo jak w przypadku normalnej deklaracji stylu.
//CSSKeyframesRule
{
   cssRules: { //CSSRuleList
         0: {//CSSKeyframeRule
           cssText: "0% { margin-left: 0px; }",
           keyText: "0%",
           parentRule: CSSKeyframesRule,
           parentStyleSheet: CSSStyleSheet,
           style: CSSStyleDeclaration,
           type: 9 // WEBKIT_KEYFRAME_RULE
         },
         1: {/*...*/}, //CSSKeyframeRule

        length: 2
   }
   cssText: "@-webkit-keyframes resize-right {  0% { margin-left: 0px; }  100% { margin-left: -2700px; }}",
   name: "resize-right",
   parentRule: null,
   parentStyleSheet: CSSStyleSheet,
   type: 8 // WEBKIT_KEYFRAMES_RULE
}
Ciekawym dodatkiem do definicji animacji jest ich nazwa (atrybut name). Dlatego też można stworzyć proste metody przeszukiwania stylów tak, aby znaleźć ten którego szukamy.

Teraz jeszcze kilka słów o dialektach, czyli czym się różnią przeglądarki w impelementacji rozwiązań.

Chrome (WebKit)

Ma dodatkowe metody findRule w przypadku obiektu CSSKeyframesRule, co pomaga odnieść się bezpośrednio do stylu na zadanym etapie (np. 0%, 50% itp.).

Przykład:

Definicja CSS
@-webkit-keyframes resize-right {
   0% {margin-left:0px;}
   100% {margin-left:-2700px;}
}

Wyniki wyszukiwania w JS
document.styleSheets[0].rules[1].findRule('0%')
// return WebKitCSSKeyframeRule

document.styleSheets[0].rules[1].findRule('10%')
// return null

Firefox

Firefox wprowadza pełną obsługę animacji od wersji 5. Dopiero wówczas listowanie arkuszy bierze pod uwagę także definicje animacji.

Z moich obserwacji wynika, że bezpośrednio zmiana stylów (w animacjach) powoduje crash przeglądarki (mniej więcej po trzeciej zmianie). Wówczas przydają się metody insertRule oraz deleteRule, dzięki którym możemy emulować sytuację modyfikacji.

Opera

Nie obsługuje animacji CSS3 (przynajmniej do wersji 11.50), więc nie ma problemów z animacjami. Metody insertRule oraz deleteRule działają jak należy. Co ciekawe stałe w CSSRule zawierają już KEYFRAMES_RULE oraz KEYFRAME_RULE.

Prześlij dalej:

Brak komentarzy:

Prześlij komentarz