Bilder zeitgesteuert austauschen - Beispiel für JavaScript-Programmierung

Der Kringel sollte aller halben Sekunden seine Farbe wechseln:
rot ---> grün ---> blau ---> und so weiter.
Das Bild hat die Nummer 3 und nicht die Nummer 0, da vor diesem bereits die drei Link-Bilder im grauen Balken eingebunden sind.

HTML-Quelltext im Body-Bereich:
Start des Vorganges im Body-tag:
<body onLoad="StartTimer()">

Einbindung des Bildes:
<img src="ring_rot.gif">

Einbindung der Steuerbuttons:
<form>
<input type=button value="Stop" onClick="StopTimer()">
<input type=button value="Start" onClick="StartTimer()">
</form>

Script-Quelltext im Head-Bereich:
hoch runter
<script type="text/javascript">
<!--
hoch runter
var i=0;                          /* Zähler */
var ring_rot=new Image();         /* rotes Bild-Objekt */
var ring_gruen=new Image();       /* grünes Bild-Objekt */
var ring_blau=new Image();        /* blaues Bild-Objekt */
ring_rot.src="ring_rot.gif";      /* rotes Bild-Objekt laden */
ring_gruen.src="ring_gruen.gif";  /* grünes Bild-Objekt laden */
ring_blau.src="ring_blau.gif";    /* blaues Bild-Objekt laden */
var running=0;                    /* speichert, ob aktiv */
var contin=0;                     /* speichert, ob fortzusetzen */
hoch runter
function TimerFunction()
{
  if (contin)
  {
    if (i==0) document.images[3].src=ring_rot.src;
    if (i==1) document.images[3].src=ring_gruen.src;
    if (i==2) document.images[3].src=ring_blau.src;
    i=(i+1)%3;
    MyTimeout=window.setTimeout("TimerFunction()",500);
     /* Die Anweisung für die Zeitsteuerung
        Wartezeit 500 Millisekunden */
  }
  else
    running=0;
}
hoch runter
function StopTimer()
/* Zeitschleife nicht fortsetzen */
{
  contin=0;
}
hoch runter
function StartTimer()
/* Zeitschleife fortsetzen */
{
  if (!running)
  {
    contin=1;
    running=1;
    TimerFunction(); /* neue Schleife einleiten */
  }
}
hoch runter
//-->
</script>

Anstatt des mit jedem Durchlauf wiederkehrenden Aufrufes von setTimeout(...) wäre auch ein einmaliger Aufruf von setInterval(...) denkbar gewesen. Der Abbruch würde dann über clearInterval(...) erfolgen.
Die Steuerung mittels Timeouts ist allerdings sicherer und sauberer, vor allem dann, wenn bei jedem Durchgang längere Zeit in der aufzurufenden Funktion verbracht wird. Der erneute Timeout wird im von mir verwendeten Beispiel erst nach kompletter Abarbeitung aller auszuführenden Befehle initialisiert. Der Browser bekommt so immer genug Zeit, alle Befehle der Reihe nach abzuarbeiten.
Bei der Verwendung von setInterval(...) kann es dagegen schon mal zu Unordnung kommen. In einigen Browsern sammeln sich unter Umständen noch nicht abgearbeitete Zeitgeberereignisse an, oder der nächste Funktionsaufruf startet, bevor der vorhergehende abgeschlossen wurde. Ich habe das an anderer Stelle exzessiv mit allen möglichen Browsern ausprobiert.
Die von mir bevorzugte Verwendung von setTimeout(...) ist damit die "staufreie" und sicherere, wenn auch unter Umständen langsamere Variante.
Auf Geschwindigkeit und präzise Zeitsteuerung darf man bei JavaScript jedoch sowieso nie setzen.
Außerdem sollte nie mehr als ein Timeout gleichzeitig laufen, mancher Browser bricht ältere Timeouts zugunsten neuer ab, weil er nicht mehr als einen Timeout gleichzeitig bearbeiten kann. Der Konqueror 1.9.8 ist solch ein Kandidat. Irgendwie muß man also manchmal mehrere eigentlich unabhängige Abläufe im Interesse der Kompatibilität unter den Hut einer gemeinsamen Zeitsteuerung bringen. Auch das geht und ist gar nicht so kompliziert.

Autor: Ulrich Kritzner