19.5 Manipulation von Bildern
Ein Bildobjekt im HTML-Dokument kann mithilfe von klassischem JavaScript nicht geändert werden: Die Position, die Anzeigegröße auf der Seite und der visuelle Inhalt eines bestimmten Bildes sind vordefiniert. Es besteht jedoch die Möglichkeit, an der Position, an der ein Bild angezeigt wird, nachträglich ein anderes anzuzeigen. Für JavaScript ist ein Bildobjekt eine Anzeigeposition für Bilder im Dokument; die wichtigste Eigenschaft – die Quell-URL src – kann nachträglich geändert werden.
Alle Bilder im Dokument befinden sich in dem Array document.images[]. Jedes Bild kann entsprechend durch seine Position im Dokument angesprochen werden:
document.images[0] // erstes Bild im Dokument
document.images[7] // achtes Bild im Dokument usw.
Alternativ ist es möglich, einem Bild einen Namen zu geben. Dafür müssen Sie zu dem HTML-Tag <img> das Attribut name="Bildname" hinzufügen. Wie bei Formularen entstehen dadurch zwei weitere Zugriffsmöglichkeiten:
- der Bildname als Objektbezeichner: document.Bildname
- der Bildname als Hash-Index: document.images["Bildname"]
Die Eigenschaft eines Bildes, die geändert wird, um ein anderes Bild an die entsprechende Stelle zu setzen, ist Bildobjekt.src – der neue Wert muss eine gültige URL sein.
19.5.1 Erstes Beispiel: Austauschen eines Bildes auf Knopfdruck
Auf einer Seite wird das 100 × 40 Pixel große Bild vorher.gif angezeigt. Bei Klick auf einen danebenstehenden Link wird es durch das Bild nachher.gif ersetzt.
Die einfachste Art, einen Hyperlink mit dem Aufruf von JavaScript zu beauftragen, besteht in der Verwendung einer "javascript:"-Pseudo-URL:
Es wird also nicht das (ebenfalls funktionierende)
<a href="#" onclick="tuWas();">Los!</a>
verwendet, sondern die einfachere Form:
<a href="javascript:tuWas();">Los!</a>
Der fertige HTML-Code im Body sieht folgendermaßen aus:
<img src="vorher.gif" name="bild" width="100" height="40"
alt="Das Wechselbild" />
<a href="javascript:wechsel();">Ändern!</a>
Die im Head definierte Funktion wechsel lautet so:
function wechsel() {
document.images[0].src = "nachher.gif";
}
Die eigentliche Bildwechselanweisung
document.images[0].src = "nachher.gif";
funktioniert in dieser Schreibweise allerdings nur dann, wenn es sich bei dem auszutauschenden Bild um das erste auf der Seite handelt. Sicherer sind die Schreibweisen
document.bild.src = "nachher.gif";
oder
document.images["bild"].src = "nachher.gif";
– wie Sie zuvor im HTML-Code sehen, wurde dem Bild das name-Attribut mit dem Wert "bild" zugewiesen.
Um daraus ein einfaches Rollover zu basteln, können Sie den separaten Hyperlink weglassen und stattdessen das Bild selbst als Link verwenden. Die beiden Event Handler onmouseover und onmouseout sorgen dafür, dass ein Link für Mausberührungen empfindlich wird.
Diese beiden Event Handler rufen die selbst definierten Funktionen rollover() und rollout() auf:
function rollover() {
document.bild.src = "nachher.gif";
}
function rollout() {
document.bild.src = "vorher.gif";
}
Im HTML-Body werden folgender Link- und Bild-Code notiert:
<a href="#" onmouseover="rollover();" onmouseout="rollout();"><img
src="vorher.gif" name="bild" width="100" height="40" alt="Rollover-Bild"
border="0" /></a>
19.5.2 Vorausladen von Bildern
Ein großes Problem bei der bisherigen Rollover-Lösung besteht darin, dass das Austauschbild erst dann geladen wird, wenn der Mauszeiger das ursprüngliche Bild berührt, sodass sich eine zu große Verzögerung ergibt.
Die Lösung besteht darin, dass Bilder mithilfe von JavaScript vorausgeladen werden können. Sie können also geladen werden, obwohl sie nicht im HTML-Code eines Dokuments angefordert werden.
Zu diesem Zweck werden unabhängige Bildobjekte (Image-Objekte) eingesetzt. Wie Bilder auf einer Seite besitzen diese Objekte die Eigenschaft src, die Quell-URL. Sobald diese zugewiesen wird, beginnt der Browser im Hintergrund mit dem Laden des entsprechenden Bildes. Wird es dann später durch Rollover angefordert, befindet es sich bereits im Browser-Cache.
Ein Image-Objekt wird folgendermaßen erzeugt:
RefVar = new Image();
Anschließend wird eine Bilddatei in das Image-Objekt geladen:
RefVar.src = "Bild_URL";
Für das erste Rollover-Beispiel müsste also über den Funktionen der folgende globale Code ergänzt werden:
var ladebild = new Image();
ladebild.src = "nachher.gif";
Alternativ kann dieser Code auch in einer separaten Funktion stehen, die durch onload aufgerufen wird.
19.5.3 Eine gut funktionierende Rollover-Lösung
In den letzten Jahren habe ich immer wieder mit verschiedenen Rollover-Ansätzen experimentiert. Herausgekommen ist letztendlich eine recht brauchbare und allgemeingültige Lösung, die es ermöglicht, auf einer Seite beliebig viele Rollover-Hyperlinks an jeder gewünschten Stelle einzusetzen.
Hier zunächst der vollständige HTML-Code eines Dokuments, das diese Lösung einsetzt. Die numerischen JavaScript- und HTML- Kommentare 1 bis 7 beziehen sich auf die im weiteren Verlauf folgende technische Dokumentation:
<html>
<head>
<title>Sicheres Rollover</title>
<script language="JavaScript"
type="text/javascript">
<!--
/* Bilder vorausladen */
// Grundbildnamen anlegen:
var bildnamen = new Array
("home", "news", "mail"); // - 1 -
// Die verschiedenen Bildobjekt-Arrays anlegen:
var normbilder = new Array();
var rollbilder = new Array();
// Die einzelnen Bildobjekte erzeugen und die
// Bilddateien hineinladen:
for (i = 0; i < bildnamen.length; i++) {
// - 2 -
var key = bildnamen[i]; // - 3 -
normbilder[key] = new Image(); // - 4 -
normbilder[key].src = key + "0.gif";
rollbilder[key] = new Image();
rollbilder[key].src = key + "1.gif";
}
/* Die eigentliche Austausch-Funktion */
function swapImage(bildname, zustand) {
// - 5 -
if (zustand == 1) { // - 6 -
// zustand 1 ist Rollover:
document.images[bildname].src =
rollbilder[bildname].src;
} else {
// Zurück zum Normalzustand:
document.images[bildname].src =
normbilder[bildname].src;
}
}
//-->
</script>
</head>
<body>
<h1>Nur Test...</h1>
<!-- 7 -->
<a href="#" onmouseover="swapImage('home', 1);"
onmouseout="swapImage('home', 0);"><img
src="home0.gif" name="home" width="50" height="30"
alt="Home" border="0" /></a><br />
<a href="#" onmouseover="swapImage('news', 1);"
onmouseout="swapImage('news', 0);"><img
src="news0.gif" name="news" width="50" height="30"
alt="News" border="0" /></a><br />
<a href="#" onmouseover="swapImage('mail', 1);"
onmouseout="swapImage('mail', 0);"><img
src="mail0.gif" name="mail" width="50" height="30"
alt="Mail" border="0" /></a><br />
<h2>Das war's...</h2>
</body>
</html>
Die folgenden Grundregeln müssen beachtet werden, wenn Sie diese Lösung für eigene Dokumente einsetzen möchten:
- Die Reihenfolge der Rollover-Bilder im Dokument ist egal – obwohl es logischer ist, ihre Namen im Skript in der gleichen Reihenfolge zu definieren, in der sie im Body auftauchen.
- Es ist erst recht egal, wie viele Nicht-Rollover-Bilder davor oder dazwischen eingeschoben werden – dies beseitigt eine der Hauptschwächen der üblichen Rollover-Lösungen.
- Jedes Bildpaar aus »Normal«-Bild und Rollover-Bild benötigt einen eindeutigen Grundnamen. Beispielsweise könnte der Grundname home lauten; die beiden konkreten Bilder wären dann home0.gif und home1.gif für den Normal- beziehungsweise Rollover-Zustand.
- Der Name des Normalbildes muss die 0 hinter dem Grundnamen tragen, beim Rollover-Bild ist es die 1.
- Ist die Endung .jpg oder .png statt .gif, müssen Sie dies nicht nur im Body beim Einbetten der Bilder anpassen, sondern auch
beim Vorausladen. Beispiel:
rollbilder[key].src = key + "1.jpg";
Innerhalb einer Seite funktioniert diese Lösung jedoch immer nur mit GIFs, nur mit JPEGs oder nur mit PNGs. Um diese Einschränkung zu umgehen, müssten Sie mehrere Funktionen (swapGIFs(), swapJPEGs() und so weiter) und pro Dateityp einen eigenen Satz globaler Variablen wie rollgifs, normgifs, gifnamen und rolljpegs, normjpegs, jpegnamen anlegen. Selbst dann benötigt immer noch jedes einzelne Bild einen individuellen Grundnamen.
- Wenn die Bilder in einem anderen Verzeichnis liegen als das HTML-Dokument, müssten
Sie auch das beim Vorausladen angeben. Befinden sich die Bilder beispielsweise in
../bilder, wird der Code folgendermaßen angepasst:
normbilder[key].src = "../bilder/" + key + "0.gif";
- Im Body muss ein Bild, das diese Funktionalität nutzen soll, auf diese Weise eingebettet
werden (hier am Beispiel eines Bildes mit dem Grundnamen test):
<a href="Ziel-URL" onmouseover="swapImage
('test', 1);" onmouseout="swapImage
('test', 0);"><img src="test0.gif" name="test"
... /></a>Wichtig sind hier vor allem diese Punkte:
- Der Grundname muss als erstes Argument in den Funktionsaufrufen bei den Event Handlern angegeben werden.
- Je nach Event Handler muss der korrekte Zustand als zweites Argument beim Funktionsaufruf angegeben werden: 1 bei onmouseover, 0 bei onmouseout.
- Im src-Attribut von <img> muss der korrekte Bilddateiname angegeben werden: [grundname]0.gif (siehe die soeben beschriebene Diskussion bezüglich eines anderen Dateityps oder anderen Pfades).
- Im name-Attribut muss der Grundname als Wert angegeben werden.
Die Nummern der folgenden Aufzählung beziehen sich auf die nummerierten Kommentare im Listing zuvor.
- Es wird ein neues Array namens bildnamen angelegt, in dem die »Grundnamen« der beteiligten Bilder aufgelistet sind. Diese
werden verwendet
- als Hash-Indizes (Schlüssel) für den Zugriff auf die Arrays, die die Bildobjekte enthalten,
- als Hash-Indizes für den Zugriff auf die Bilder im Dokument (document.images[]) sowie
- als »Wurzelbestandteil« zur Komposition der Bilddateinamen.
Diese identische Benennung auf drei wichtigen Ebenen (Bildobjekte im Dokument, Bilddateinamen und unabhängige Bildobjekt-Arrays) vereinfacht den Zugriff und das Zusammenspiel aller Komponenten.
- Alle Elemente des Bildnamen-Arrays – und damit alle vorauszuladenden Bilder – werden
nacheinander in einer Schleife behandelt:
for (i = 0; i < bildnamen.length; i++) { ... }
Die Zählervariable i beginnt bei 0, dem Index für das erste Element von bildnamen. Dabei muss i so viele Durchläufe erleben, wie bildnamen Elemente besitzt. Die Anzahl der Elemente eines Arrays erhalten Sie durch die Eigenschaft ArrayVar.length.
- Das aktuelle Element des Arrays bildnamen, das im momentanen Schleifendurchlauf an der Reihe ist, wird in der Variablen key abgelegt. Rein theoretisch können Sie sich diesen Schritt sparen und überall, wo
im weiteren Verlauf des Schleifenrumpfs key steht, synonym bildnamen[i] eintragen. Allerdings wären Formulierungen wie diese ein wenig umständlich:
normbilder[bildnamen[i]] = new Image();
normbilder[bildnamen[i]].src =
bildnamen[i] + "0.gif"; - Für das aktuelle Element des Bildobjekt-Arrays normbilder[] wird ein neues Bildobjekt erstellt. Beachten Sie, dass der Index für dieses Array
nicht der numerische Wert i ist, sondern der Zeichenkettenwert, der in Schritt 3 aus bildnamen[] heraus in der Variablen key abgelegt wurde.
In der nächsten Zeile wird als Quell-URL (src) des neuen Bildobjekts der zusammengesetzte Dateiname festgelegt: Der in key gespeicherte Grundbildname, die 0 für »Normalzustand« und die Endung (hier .gif) werden verkettet. Sollten die Bilder in einem anderen Verzeichnis liegen, muss dies noch vor dem Wert key angegeben werden. Durch diese zweite Zeile wird das eigentliche Vorausladen in Gang gesetzt.
Dasselbe geschieht in den nächsten beiden Zeilen für das entsprechende Rollover-Bild. Das Array ist hier allerdings nicht normbilder[], sondern rollbilder[], und statt der 0 als Namensbestandteil für ein »Normalbild« wird die 1 für ein Rollover-Bild notiert.
- Der Funktionskopf der Funktion swapImage() ist so definiert, dass die Funktion zwei Argumente erwartet, nämlich Werte für die
Parametervariablen bildname und zustand.
Wenn die Funktion später aus Event Handlern im Body aufgerufen wird, müssen stets zwei Werte übergeben werden: bildname enthält dabei den jeweiligen Grundnamen; zustand bezeichnet die Zustände »Normal« oder »Rollover«, wieder durch 0 beziehungsweise 1 notiert.
- Hat der übergebene Wert von zustand den Wert 1, handelt es sich um den Rollover-Zustand: Die Quell-URL des durch den
Index bildname bezeichneten Bildes im Dokument (document.images[bildname].src) wird auf die Quell-URL des entsprechenden Elements im Array rollbilder[] gesetzt, also auf den Wert rollbilder[bildname].src.
Ebenso läuft das Ganze ab, wenn der else-Teil aktiviert wird. Dieser ist für den Zustand 0 zuständig. Es wird entsprechend das aktuelle Normalbild eingestellt, indem das durch bildname indizierte Bild im Dokument auf die Quell-URL des entsprechenden Elements von normbilder[] gesetzt wird.
- In den Hyperlinks im Dokument rufen die beiden Event Handler onmouseover und onmouseout jeweils die Funktion swapImage() auf. onmouseover bedeutet, dass der Mauszeiger den Bereich des Links berührt, und löst deshalb zum
Beispiel die folgende Anweisung aus:
swapImage('home', 1);
'home' muss hier natürlich je nach konkretem Bild ausgetauscht werden; die 1 beschreibt dagegen stets den Zustand »Rollover«.
onmouseout bedeutet dagegen, dass der Mauszeiger den Linkbereich verlässt, weshalb in dem entsprechenden Aufruf
swapImage('home', 0);
der Zustandswert 0 verwendet wird.
Ihr Kommentar
Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.