Glow — Manipulation am Stylesheet

Experimente mit Javascript und dem Stylesheet-DOM

Während der letzten autodidaktischen Fortbildung habe ich mich mit dem Document Object Module der Stylesheets befasst. Kann ich die Farbe einer CSS-Klasse dynamisch ändern? Gleich wie beim HTML-DOM können in Theorie CSS-Regeln als Knoten ausgelesen, gelöscht, umgeschrieben oder hinzugefügt werden. Leider scheint die Implementierung uneinheitlich, das Finden eines bestimmten Knotens eine aufwändige Objektbaum-Traverse, wobei die Details von Browser zu Browser variieren. Mit einem Trick lässt sich die Suche aber umgehen: Es reicht, eine neue Regel mit der gewünschten Definition ans Ende der bestehenden Regeln anzuhängen, da in CSS spätere Regeln frühere überschreiben. Weil der Index der hinzugefügten Regel bekannt ist, kann später leicht auf den Knoten zugegriffen werden.

Das Skript glow.js

Hier nun das Glow-Skript in Aktion. Die Farbe aller HTML-Elemente, die mit der CSS-Klasse class="glow" ausgezeichnet sind (zum Beispiel dieser Absatz), pulsiert kontinuierlich zwischen zwei festgelegten Farbwerten.

Je nach verwendetem CSS-Selektor können andere Seitenelemente angesprochen werden

Bemerkungen zum Skript

Quelltext des aktuell verwendeten Skripts:

// Simple JavaScript Glow Effect
// (c) endo.ch 2008, Christoph Berger, www.endo.ch

var rgb1 = [255, 0, 255];
var rgb2 = [255, 128, 0];
var styleSelector= '#maincontent a, #maincontent a:visited, #menu.light a, #menu.dark a, #mainservice a';
var step = 4;
addListener(window, 'load', startglow);  

function glow(count)
{
  // count:  0 bis 50 (zunehmend) 50 bis 100 (abnehmend)  
  var prog = (count > 50)  ? 100-count : count;
  
  var rgbNew =[
    Math.floor(rgb1[0]+prog*(rgb2[0]-rgb1[0])/50),
    Math.floor(rgb1[1]+prog*(rgb2[1]-rgb1[1])/50),
    Math.floor(rgb1[2]+prog*(rgb2[2]-rgb1[2])/50)
  ];
  
  var color = 'rgb('+rgbNew[0]+','+rgbNew[1]+','+rgbNew[2]+')';
  
  for(s=0; s<styleSelector.numOfRules; s++){
    styleSelector.ruleSet[styleSelector.ruleIndex+s].style.color = color;
  }
  
  window.setTimeout('glow('+((count+step)%100)+')', 150);
}

function startglow()
{
  var property = 'color: rgb('+rgb1[0]+','+rgb1[1]+','+rgb1[2]+')';
  var i = document.styleSheets.length-1;
  var ruleSet = (document.styleSheets[i].cssRules) ? document.styleSheets[i].cssRules : document.styleSheets[i].rules;
  var index = ruleSet.length;
  
  var selectors = new Array();
  var numOfRules = 0;
  if (document.styleSheets[i].addRule){
    // IE braucht für jeden Selektor eine eigene Regel
    selectors = styleSelector.split(',');
    numOfRules = selectors.length;
    for(s=0; s<numOfRules; s++){
      document.styleSheets[i].addRule( selectors[s], property, index+s );
    }
  }
  else{
    numOfRules = 1;
    document.styleSheets[i].insertRule( styleSelector+' {'+property+'}', index );
  }
  // Safari Bug?? ruleSet neu zuweisen
  ruleSet = (document.styleSheets[i].cssRules) ? document.styleSheets[i].cssRules : document.styleSheets[i].rules;
  
  styleSelector = {'ruleSet': ruleSet, 'ruleIndex': index, 'numOfRules':numOfRules };  // globale Variable
  
  glow(0);
}

function addListener(element, event, listener, bubble) 
{
  if(element.addEventListener) {
    if(typeof(bubble) == "undefined") bubble = false;
    element.addEventListener(event, listener, bubble);
  } else if(document.attachEvent) {
    element.attachEvent("on" + event, listener);
  }
}

Fazit

Das Experiment ist zweifelsfrei geglückt. Es stellt sich dennoch die Frage: Wozu kann ich die Erkenntnisse verwenden? Erst gerade wurde das Verschwinden des blink-Tags gefeiert, und nun dies! Manchmal bin ich entsetzt ab mir selber.

© 2007-2024 endo.ch • Seite zuletzt geändert am 7. März 2018

Beginn des Sidebarbereichs