Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
1 Einleitung
2 Webbrowser
3 JavaScript einbauen
4 Programmieren mit JavaScript
5 Datum
6 Zufall
7 Browserinformationen
8 Fenster
9 Formulare
10 Frames und Iframes
11 Grafiken
12 Cookies
13 Objekte und Arrays
14 Ereignisbehandlung
15 Fehlerbehandlung
16 DOM
17 DHTML und CSS
18 AJAX
19 XML
20 Web Services
21 AJAX-Frameworks
22 Plugins
23 Multimedia
24 Java
25 Serverseitige Technologien
26 JavaScript goes .NET
27 Code schützen
28 Top Secret: Passwortschutz
29 Signierte Skripte
30 JavaScript und Sicherheit
31 Navigation
32 Warenkorb
33 JavaScript-Bibliotheken
34 Referenz
35 Quellen im Web
36 Die Zukunft von JavaScript
Index
Download: - ZIP, ca. 9,2 MB
Buch bestellen
Ihre Meinung?
<< zurück | Galileo Computing / <openbook> / JavaScript und AJAX | vor >>
JavaScript und AJAX von Christian Wenz Das umfassende Handbuch
JavaScript und AJAX 839 S., mit DVD, 39,90 Euro Galileo Computing ISBN 3-89842-859-1 |
| Kapitel 11 Grafiken
|  | 11.1 Bildlein-Wechsle-Dich
|  |  | 11.1.1 Zugriff auf Grafiken
|  | 11.2 Animierte JPEGs
|  |  | 11.2.1 Eine Animation mit JavaScript
|  |  | 11.2.2 Bilder in den Cache laden
|  | 11.3 Animierte Navigation
|  |  | 11.3.1 Vorüberlegungen
|  |  | 11.3.2 Auf- und Zuklappen
|  |  | 11.3.3 Die einzelnen Menüpunkte
|  |  | 11.3.4 Verlinkung der Menüpunkte
|  |  | 11.3.5 Einbau in die HTML-Datei
|  | 11.4 Erweiterung der Navigation
|  |  | 11.4.1 Vorbereitungen
|  |  | 11.4.2 Leichte Änderungen
|  |  | 11.4.3 Doppeltes Mouseover
|  |  | 11.4.4 Das komplette Beispiel im Überblick
|  | 11.5 Tipps aus der Praxis
|  |  | 11.5.1 Vorladen – aber richtig
|  |  | 11.5.2 Ladestand einer Grafik
|  |  | 11.5.3 Fortschrittsanzeige
## 11.5 Tipps aus der Praxis In diesem letzten Abschnitt dieses Kapitels über das Image-Objekt möchte ich Ihnen noch ein paar Tipps aus der Praxis geben, damit Sie Fehlermeldungen vermeiden oder Ihre Seiten mit noch mehr Funktionalität versehen können. Das Image-Objekt wird sehr gern eingesetzt, und ein paar Fehler werden immer wieder gemacht, ein paar Fragen immer wieder gestellt. Die folgenden zwei Abschnitte beantworten hoffentlich die Fragen, die Sie noch haben. ### 11.5.1 Vorladen – aber richtig Sie haben sich vielleicht gefragt, warum beim Beispiel zum Vorladen die Funktion preload() nicht mittels <body onload="preload();"> aufgerufen worden ist, sondern noch im <head>-Abschnitt des HTML-Dokuments. Das hat einen einfachen Grund. Gehen Sie von einer langsameren Verbindung oder von einem umfangreichen Dokument aus. Ein Teil des HTML-Dokuments wurde schon übertragen und ist auch schon vom Browser dargestellt worden. Hier ist besonders der Internet Explorer sehr schnell, während manche andere Browser Tabellen erst dann anzeigen, wenn sie vollständig übertragen worden sind. Aber zurück zum Beispiel: Ein Teil der Seite ist also schon geladen und wird dargestellt – und die Event-Handler in diesem Teil sind natürlich aktiv. Wie es der Zufall so will, fährt der Benutzer jetzt schon über eine mit Mouseover versehene Grafik. Im Beispiel von oben würde nun die folgende Funktion aufgerufen werden:
    function over() {
       document.grafik.src = img_over.src;
    }
Die Variable img_over wird aber erst in der Funktion preload() korrekt gesetzt. Das ist schlecht, wenn die Funktion erst mit dem onload-Event-Handler aufgerufen wird; wie Sie sich erinnern, tritt dieser erst in Aktion, wenn das gesamte HTML-Dokument übertragen worden ist. Es gäbe also in diesem Fall unter Umständen eine Fehlermeldung. Um dies zu vermeiden, rufen Sie Ihre Vorladefunktion noch vor dem ersten <img>-Tag auf! ### 11.5.2 Ladestand einer Grafik JavaScript bietet dem Benutzer eine bequeme Möglichkeit festzustellen, wie weit eine Grafik schon geladen ist. Interessant wird das beispielsweise bei der Diashow aus Kapitel 10. Wenn Sie die Diashow über eine langsame Netzwerkverbindung abspielen, kann es sein, dass umfangreiche Grafiken auf den einzelnen Seiten der Show noch nicht vollständig geladen sind, bevor die nächste Seite der Show angezeigt wird. Es wäre hier also praktisch, wenn die Grafiken alle schon vorher im Browsercache wären. Auch beim Beispiel mit der JPEG-Animation aus diesem Kapitel ist das wünschenswert. Wir wollen für das letztere Beispiel eine Lösung konstruieren, die analog auch für das Diashow-Beispiel eingesetzt werden kann. Der Trick besteht darin, eine Einstiegsseite zu programmieren, auf der alle Grafiken schon einmal geladen werden. Nun könnte man einerseits den Benutzer nach Ablauf einer gewissen Zeitspanne auf die nächste Seite weiterleiten, aber das ist keine sehr flexible Lösung. Bei einer langsamen Verbindung reicht die Zeit nicht aus, und bei einer schnellen Verbindung dauert das Warten zu lange. Ein erster Ansatz besteht darin, den Event-Handler onload zu benutzen. Den gibt es auch bei Grafiken. Sobald bei jeder Grafik der onload-Event-Handler ausgeführt worden ist, kann auf die nächste Seite weiterverzweigt werden. Zudem sollte man nach einer bestimmten Zeit ohnehin zur nächsten Seite übergehen, um die Geduld des Benutzers nicht allzu sehr zu strapazieren.
    <html>
    <head>
    <meta http-equiv="refresh"
    content="30;url=animation.html" />
    <!-- nach 30 Sekunden wird die Seite animation.html geladen -->
    <title>Animation vorbereiten</title>
    <script type="text/javascript"><!--
    var geladen = 0;  //Anzahl der fertig geladenen Grafiken
    function fertig() {
       geladen++;
       if (geladen==4) { //wenn alle Grafiken geladen sind
          location.href = "animation.html";
       }
    }
    //--></script>
    </head>
    <body>
    <h3>Animation lädt... Bitte warten...</33>
    <img src="ani1.jpg" onload="fertig();" width="1" height="1" />
    <img src="ani2.jpg" onload="fertig();" width="1" height="1" />
    <img src="ani3.jpg" onload="fertig();" width="1" height="1" />
    <img src="ani4.jpg" onload="fertig();" width="1" height="1" />
    </body>
    </html>
Jedes Mal, wenn eine Grafik fertig geladen worden ist, wird ein Zähler um eins erhöht, und es wird überprüft, ob damit die magische Zahl 4 (die Anzahl der Grafiken) erreicht worden ist. Dieses Vorgehen funktioniert unter gewissen Umständen nicht – vor allem auf älteren Rechnern mit wenig Speicher. Wenn zwei Grafiken quasi gleichzeitig vollständig geladen worden sind und dadurch die Funktion fertig() zweimal aufgerufen wird, kann es vorkommen, dass einer der Aufrufe verschluckt wird. Wie gesagt, das kommt ganz selten vor, aber es gibt Zeugen ... Hier hilft Ihnen vielleicht die Eigenschaft complete eines Image-Objekts. Dieses gibt an, ob eine Grafik vollständig geladen worden ist (true) oder nicht (false). In der Funktion fertig() wird also jetzt kein Zähler heraufgesetzt, sondern überprüft, ob alle Grafiken vollständig geladen worden sind. Falls ja, wird zur Animationsseite übergegangen. Auch diese Eigenschaft wird von den verschiedenen Browsern unterschiedlich gut (oder schlecht) unterstützt. Im folgenden Listing lernen Sie außerdem noch eine Anwendungsmethode für die Event-Handler onabort und onerror kennen. onabort tritt dann in Aktion, wenn der Benutzer das Laden mit der Schaltfläche Stop abbricht; onerror wird aktiv, wenn ein Fehler bei der Übertragung auftritt (beispielsweise, wenn die Grafikdatei nicht existiert).
    <html>
    <head>
    <meat http-equiv="refresh"
    content="30;url=animation.html" />
    <!-- nach 30 Sekunden wird die Seite animation.htm
    geladen -->
    <title>Animation vorbereiten</title>
    <script type="text/javascript"><!--
    function fertig() {
       if (document.images[0].complete && document.
       images[1].complete && document.images[2].complete &&
       document.images[3].complete) {
          location.href = "animation.html";
       }
    }
    function abbruch() {
       alert("Sie wollen das Laden abbrechen? Na gut,
       wir leiten Sie weiter...");
       location.href = "animation.html";
    }
    function fehler() {
       alert("Beim Laden einer der Grafiken ist ein Fehler
       aufgetreten. Wir leiten Sie trotzdem weiter...");
       location.href = "animation.html";
    }
    //--></script>
    </head>
    <body>
    <h1>Animation lädt... Bitte warten...</h1>
    <img src="ani1.jpg" onload="fertig();"
    onAbort="abbruch();" onError="fehler();" width="1" height="1" />
    <img src ="ani2.jpg" onload="fertig();"
    onAbort="abbruch();" onError="fehler();" width="1" height="1" />
    <img src ="ani3.jpg" onload="fertig();"
    onAbort="abbruch();" onError="fehler();" width="1" height="1" />
    <img src ="ani4.jpg" onload="fertig();"
    onAbort="abbruch();" onError="fehler();" width="1" height="1" />
    </body>
    </html>
Leider wird onerror nicht mitgeteilt, welche der Grafiken beim Laden einen Fehler hatte. Man könnte diese Information aber als Parameter an die Funktion fehler() übergeben. Hier klicken, um das Bild zu Vergrößern Abbildung 11.5 Die Meldung, die erscheint, wenn eine der Grafiken nicht existiert ### 11.5.3 Fortschrittsanzeige Flash-Filme können es – mit etwas Mühe. Normale HTML-Seiten können es auch – in der Statuszeile des Browsers. Die Rede ist von Fortschrittsanzeigen, die angeben, wie viel von dem Inhalt einer Seite oder eines Films schon geladen worden ist. In Bezug auf Grafiken ist das mit der complete-Eigenschaft von Grafiken möglich. Zunächst erstellen wir eine Fortschrittsanzeige, die angibt, wie viele Grafiken der aktuellen Seite bereits übertragen worden sind. Das Vorgehen ist das Folgende:
| Eine Funktion durchläuft alle Grafiken in der HTML-Seite und überprüft die complete-Eigenschaft.
| Die Anzahl der bereits vollständigen Grafiken wird durch die Anzahl der insgesamt zu ladenden Grafiken geteilt.
| Dieser Wert wird in der Statuszeile ausgegeben.
| Falls der Wert noch nicht 100 % entspricht, wird die Funktion per Timeout wieder aufgerufen.
    function fortschritt() {
       var gesamt = document.images.length;
       var geladen = 0;
       for (var i=0; i<gesamt; i++) {
          if (document.images[i].complete) {
             geladen++;
          }
       }
        if (gesamt > 0) {
          window.status = "Geladen: " +
                          Math.round(100*geladen/gesamt) + "%";
        }
       if (gesamt > geladen) {
          setTimeout("fortschritt();", 500);
       }
    }
Beachten Sie, dass Sie die Funktion erst aufrufen dürfen, wenn das HTML-Dokument vollständig geladen worden ist. Nachfolgend sehen Sie ein exemplarisches HTML-Dokument – mit Statusanzeige:
    <html>
    <head>
    <title>Fortschrittsanzeige</title>
    <script type="text/javascript"><!--
    function fortschritt() {
       var gesamt = document.images.length;
       var geladen = 0;
       for (var i=0; i<gesamt; i++) {
          if (document.images[i].complete) {
             geladen++;
          }
       }
        if (gesamt > 0) {
          window.status = "Geladen: " +
                          Math.round(100*geladen/gesamt) + "%";
        }
       if (gesamt > geladen) {
          setTimeout("fortschritt();", 500);
       }
    }
    //--></script>
    </head>
    <body onload="fortschritt();">
    <img src="1.png" /><img src="2.png" /><img src="3.png" />
    </body>
    </html>
Auf der Buch-DVD finden Sie noch eine weitere Datei (warten.php), die jedoch PHP voraussetzt. Anstelle von Grafikdateien lädt dort der JavaScript-Code eine PHP-Datei, die ein paar Sekunden wartet und dann erst die Dateien 1.png bis 3.png lädt. Somit geht die Fortschrittsanzeige nur schrittweise voran, und der Effekt ist besser zu beobachten. Was für die aktuelle Seite gilt, kann auch für den Rest der Website gelten. Zwar ist es unsinnig, die Grafiken für die gesamte Site im Browser-Cache zu halten, aber zumindest oft verwendete Grafiken sollten Sie möglichst früh laden. Dazu gehören:
| das Firmenlogo (es kommt bestimmt auf jeder Seite vor)
| Navigationsgrafiken (die auch auf fast jeder Seite verwendet werden)
| weitere häufig verwendete Grafiken, zum Beispiel Füllgrafiken
Ein möglicher Ansatz besteht darin, diese Grafiken auf der Startseite des Angebots bereits zu laden und nach dem erfolgten Laden erst den Zugang zum restlichen Angebot zu eröffnen. Dazu muss die Funktion fortschritt() ein wenig umgeschrieben werden (beziehungsweise eine Funktion programmiert werden, die Ähnliches wie fortschritt() leistet), damit Folgendes gewährleistet ist:
| Der Prozentsatz der bereits vollständig geladenen Grafiken der Webseite wird ermittelt.
| Dieser Prozentsatz wird zurückgegeben.
| Eine Funktion gibt den aktuellen Prozentwert an geeigneter Stelle aus.
| Sobald der Prozentwert 100 % beträgt, wird die Hauptseite des Angebots geladen.
Kommen wir zunächst zu der Funktion, die zurückliefert, wie viele der Grafiken der Webseite bereits vollständig geladen worden sind:
    function geladen() {
       var gesamt = document.images.length;
       var geladen = 0;
       for (var i=0; i<gesamt; i++) {
          if (document.images[i].complete) {
             geladen++;
          }
        }
       if (gesamt > 0) {
          return geladen/gesamt;
       } else {
          return 1;  // 100 Prozent
       }
    }
Die Funktion, die den gerade aktuellen Prozentwert regelmäßig ausgibt und bei 100 Prozent die nächste Seite lädt, ist folgendermaßen aufgebaut:
| Zunächst wird mit geladen() ermittelt, wie viele der Grafiken der aktuellen Seite bereits geladen worden sind:
>     var geladen = Math.round(100 * geladen());
>     geladen = "Bitte warten ... " + geladen + "%";
| Als Nächstes wird der Wert in einem <div>-Element ausgegeben, wobei wir auf DHTML und getElementById() setzen (mehr dazu erfahren Sie in Kapitel 16:
>     document.getElementById("geladen").innerHTML = geladen;
| Sobald 100 % erreicht worden sind, wird die nächste Seite aufgerufen:
>     if (geladen() == 1) {
>        location.href = "homepage.html";
>     }
| Falls 100 % noch nicht erreicht sind, wird der Code per Timeout nach kurzer Zeit wieder aufgerufen.
Im Folgenden ist der komplette Code abgedruckt. Die Weiterleitungs-URL wird in einer globalen Variablen gespeichert, um das Skript leicht anpassen zu können.
    <html>
    <head>
    <title>Fortschrittsanzeige</title>
    <script type="text/javascript"><!--
    function geladen() {
       var gesamt = document.images.length;
       var geladen = 0;
       for (var i=0; i<gesamt; i++) {
          if (document.images[i].complete) {
             geladen++;
          }
        }
       if (gesamt > 0) {
          return geladen/gesamt;
       } else {
          return 1;  // 100 Prozent
       }
    }

    var url = "homepage.html";
    function warten() {
       var geladenprozent = Math.round(100 * geladen());
       geladenprozent = "Bitte warten ... " + geladenprozent + "%";
       document.getElementById("geladen").innerHTML = geladenprozent;
       if (geladen() == 1) {
          location.href = url;
       } else {
          setTimeout("warten()", 500);
       }
    }
    //--></script>
    </head>
    <body onload="warten();">
    <div id="geladen" style="position: absolute;">
    </div>
    <img src="1.png" width="1" height="1" />
    <img src="2.png" width="1" height="1" />
    <img src="3.png" width="1" height="1" />
    </body>
    </html>
Beachten Sie, dass die width- und height-Eigenschaften der Grafiken auf "1" gesetzt worden sind, damit die Grafiken dort noch nicht angezeigt werden. Die Fortschrittsanzeige lässt sich auch grafisch darstellen. Das ist ein wenig komplizierter, und vor allem wird das Ergebnis verfälscht:
| Die Grafiken zur Anzeige der Fortschrittsanzeige müssen ebenfalls geladen werden.
| Im schlimmsten Fall werden die restlichen Grafiken vor den Grafiken des Fortschrittsbalkens geladen.
Der Rest läuft wie folgt ab:
| Es wird eine fünfstufige Fortschrittsanzeige verwendet; jede Grafik entspricht 20 Prozent.
>     <nobr><img src="rot.png" name="balken1" /><img src="rot.png" name="balken2" />
>     <img src="rot.png" name="balken3" /><img src="rot.png" name="balken4" />
>     <img src="rot.png" name="balken5" /></nobr>
| Dann wird per Timeout der momentane Ladefortschritt bestimmt.
>     var geladen = geladen();
| Der Ladefortschritt wird (gerundet) durch zwanzig dividiert. In Abhängigkeit von diesem Ergebnis werden entsprechend viele Grafiken von rot auf grün geschaltet.
>     var fortschritt = Math.round(5*geladen); // *100 / 20
>     for (var i=1; i<=fortschritt; i++) {
>        document.images["balken"+i].src = "gruen.png";
>     }
| Eine weitere Besonderheit: Damit die Fortschrittsanzeige auch komplett bewundert werden kann, erfolgt die Weiterleitung auf die nächste Seite erst nach einer kurzen Verzögerung:
>     setTimeout("location.href=\"" + url + "\"", 500);
Hier sehen Sie das komplette Skript:
    <html>
    <head>
    <title>Fortschrittsanzeige</title>
    <script type="text/javascript"><!--
    function geladen() {
       var gesamt = document.images.length;
       var geladen = 0;
       for (var i=0; i<gesamt; i++) {
          if (document.images[i].complete) {
             geladen++;
          }
        }
       if (gesamt > 0) {
          return geladen/gesamt;
       } else {
          return 1;  // 100 Prozent
       }
    }

    var url = "homepage.html";
    function warten() {
       var geladen = geladen();
       var fortschritt = Math.round(5*geladen); // *100 / 20
       for (var i=1; i<=fortschritt; i++) {
          document.images["balken"+i].src = "gruen.png";
       }
       if (geladen() == 1) {
          setTimeout("location.href = \"" + url + "\";", 500);
       } else {
          setTimeout("warten();", 500);
       }
    }
    //--></script>
    </head>
    <body onload="warten()">
    <nobr><img src="rot.png" name="balken1" /><img src="rot.png" name="balken2" />
    <img src="rot.png" name="balken3" /><img src="rot.png" name="balken4" />
    <img src="rot.png" name="balken5" /></nobr>
    <img src="1.png" width="1" height="1" />
    <img src="2.png" width="1" height="1" />
    <img src="3.png" width="1" height="1" />
    </body>
    </html>
Hier klicken, um das Bild zu Vergrößern Abbildung 11.6 Fast alle Grafiken sind schon geladen. Denken Sie auf jeden Fall daran, dass Sie für Browser ohne Unterstützung des Image-Objekts (das sind eher wenige) oder mit deaktiviertem oder fehlendem JavaScript (das sind schon mehr) auf jeden Fall noch einen Link auf die eigentliche Hauptseite des Angebots zur Verfügung stellen sollten – denn ansonsten bleibt der Benutzer auf der Einstiegsseite hängen.
<< zurück | <top> | vor >>
Zum Katalog
JavaScript und AJAX bestellen
Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen? Ihre Meinung
Buchtipps
| JavaScript und AJAX - Das Video-Training
| Webseiten programmieren und gestalten
| XHTML, HTML und CSS
| CSS-Praxis
| AJAX
| PHP 5 und MySQL 5
| TYPO3 4.0
Shopping
Versandkostenfrei bestellen in Deutschland und Österreich Info

Copyright © Galileo Press 2007
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

[Galileo Computing]
Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de