Anzeige
Tutorialbeschreibung

Javascript und Ajax - DHTML und CSS

Javascript und Ajax - DHTML und CSS

Das nun folgende Tutorial ist ein Auszug aus dem Buch: Professionelle Websites von Stefan Münz.
Die Veröffentlichung des Kapitels erfolgt mit freundlicher Genehmigung von Pearson Education.

Kapitel 17 DHTML und CSS

Allein die Erwähnung des Begriffs DHTML lässt die Augen von vielen Leuten im Web-Bereich leuchten und steigert die Auflage von vielen Zeitschriften. Doch was ist DHTML überhaupt? Die Abkürzung steht für Dynamic HTML – doch handelt es sich hierbei um eine HTML-Erweiterung oder nur um neue JavaScript-Befehle? Wenn Sie in der Marketingabteilung einer Web-Agentur nachfragen, bekommen Sie mit ziemlicher Sicherheit eine weitläufige Erklärung, die diese Technik wahlweise als »Stein der Weisen« oder als »Ei des Kolumbus« preist. Das Ziel dieses Kapitels soll es sein, dass Sie ein Gefühl dafür bekommen, was man mit DHTML machen kann. Eine vollständige Abhandlung des Themas, inklusive einer Auflistung aller Bugs werden Sie hier schon allein aus Platzgründen nicht finden.

In diesem Kapitel wird das Thema DHTML kurz allgemein beleuchtet, und dann werfen wir einen Blick auf die beiden »großen« Browsergruppen: aktuelle Mozilla-Browser und natürlich den Internet Explorer. Safari, Konqueror und Opera halten sich meist an die Mozilla-Implementierung und werden deswegen nicht gesondert aufgeführt.

Explizit nicht behandelt werden Anno-Tobak-Versionen von Browsern. Sowohl der Internet Explorer 4 als auch der Netscape Navigator 4 konnten DHTML, leider komplett unterschiedlich und zueinander inkompatibel. Die Zugriffsweise des Internet Explorer 4 ist in neueren Versionen des Internet Explorer zwar immer noch präsent, wird aber in der Regel nur noch dazu verwendet, die Browser voneinander zu unterscheiden. Und Mozilla-Browser haben sich immerhin einige Elemente des DHTML-Supports von Netscape abgeguckt.


17.1 Grundlagen 
topBilder
topBilder

Wie schon in der Einleitung angedeutet wurde, ist es nicht immer ganz leicht zu verstehen, was mit DHTML gemeint ist. In diesem Abschnitt unternehme ich den Versuch, den Begriff zu bestimmen und die notwendigen (theoretischen) Hintergründe zu erläutern. Außerdem werden die entsprechenden HTML-Tags vorgestellt.

Was ist DHTML? Jeder Entwickler und jeder Browserhersteller hat eine andere Definition parat. Da ist von viel Dynamik die Rede und von der Erfüllung aller Träume von Webentwicklern. Ich bevorzuge dagegen eine etwas einfachere, flapsigere Definition: »DHTML ist JavaScript für Browser ab Version 4« (wobei beispielsweise der Mozilla-Browser die Versionsnummer 6, 7 oder 8 hat – schließlich ist er der Netscape-Nachfolger). Diese Definition ist eine Art kleinster gemeinsamer Nenner aller konkurrierenden Beschreibungen. Aber das »D« für »Dynamic« hat schon seine Berechtigung. Mit den bisher vorgestellten JavaScript-Techniken kann man zwar auf gewisse Weise auf Benutzereingaben reagieren, aber man hat nicht viele Zugriffsmöglichkeiten auf die Elemente einer HTML-Seite. Zwar kann man mit dem Image-Objekt Grafiken austauschen, von einer Größenveränderung oder gar Verschiebung kann aber keine Rede sein. Mit DHTML ist das möglich, es ist sogar eine Art von Drag&Drop möglich.

 

17.2 Cascading Style Sheets 
topBilder
topBilder

Die herkömmliche HTML-Programmierung war nicht immer besonders strukturiert. Wollte man in einer Tabelle alle Zellen in einer bestimmten Schrift darstellen, so musste man in jeder Zelle ein <font>-Tag verwenden. Mit dem Konzept der Cascading Style Sheets (kurz CSS) kann sich das ändern. Ohne hier auf allzu viele Details eingehen zu wollen, sei nur gesagt: Es gibt immer wieder in der Fachpresse Vergleiche, welcher Browser in welchem Maße CSS unterstützt. Dabei schneidet der Netscape Navigator in der Regel am schlechtesten ab, der Internet Explorer schon etwas besser – und in Führung liegt die Nummer 3 auf dem Browser-Markt, der norwegische Opera-Browser.

Ein Style Sheet sieht folgendermaßen aus:

<style type="text/css"><!--
a {color:blue; text-decoration:none}
--></style>

Die HTML-Kommentare dienen auch hier dazu, dass ältere Browser den Text zwischen den <style>-Tags nicht anzeigen. Heutzutage ist das allerdings genauso relevant wie die HTML-Kommentare bei <script>-Tags: Sie schaden nicht, aber nützen nur begrenzt. Eigentlich interessant ist diese Zeile:

a {color:blue; text-decoration:none}

Das bedeutet: Alle Links (Tag <a>) im Text werden in blauer Farbe angezeigt (color:blue) und nicht unterstrichen (text-decoration:none). Diese Angaben gelten global für das gesamte Dokument. Man kann jedoch diese Vorgaben auch überschreiben, indem bei einem Tag der style-Parameter gesetzt wird:

<a href="http://www.galileo-press.de/" _fcksavedurl="http://www.galileo-press.de/" _fcksavedurl="http://www.galileo-press.de/" _fcksavedurl="http://www.galileo-press.de/" _fcksavedurl="http://www.galileo-press.de/" style="color:blue; text-decoration:none">Galileo Press</a>

Man kann natürlich nicht nur Links anpassen, sondern beispielsweise auch Absätze (Tag <p>) oder eben Tabellenzellen (Tag <td>):

<style type="text/css"><!--
p {color:green}
td {font-size: 12pt}
--></style>

Außerdem lassen sich CSS-Stilangaben nicht nur für Tags einrichten, sondern auch für IDs und für spezielle Klassen. Letzteres sieht beispielsweise folgendermaßen aus:

<style type="text/css"><!--
.gruen {color:green}
--></style>

Alles auf der Seite, was die Klasse gruen hat, wird auch grün dargestellt. Die Klasse geben Sie mit dem class-Attribut an:

<p class="gruen">Dieser Text ist nicht mehr schwarz ...</p>

JavaScript bietet nun mehrere Möglichkeiten, auf CSS-Formatierungen eines Elements zuzugreifen. Am einfachsten verwenden Sie die style-Eigenschaft des entsprechenden HTML-Elements, das Sie via DOM (siehe vorheriges Kapitel) »erreichen«. Sie müssen dann nur noch die zugehörige CSS-Eigenschaft in CamelCase umwandeln. Das bedeutet, dass jeder Wortbestandteil mit einem Großbuchstaben beginnt, aber die gesamte Eigenschaft mit einem Kleinbuchstaben anfängt. Aus der CSS-Eigenschaft color wird die JavaScript-Eigenschaft color, es ändert sich also nichts. Aus background-color wird backgroundColor, aus font-weight wird fontWeight. Bindestriche verschwinden also ebenfalls – sie sind ja so oder so nicht in JavaScript-Eigenschaften erlaubt.

Das folgende Listing ändert die Vorder- und Hintergrundfarbe eines Textes auf Knopfdruck. Per document.getElementById() wird das <p>-Element angesprochen und dann style.<Eigenschaft> gesetzt.

Bilder

Abbildung 17.1     Der Text wird auf Mausklick invertiert.

<html>
<head>
<title>CSS</title>
<script type="text/javascript"><!--
function normal() {
var Absatz = document.getElementById("Absatz");
Absatz.style.color = "black";
Absatz.style.backgroundColor = "white";
}

function invers() {
var Absatz = document.getElementById("Absatz");
Absatz.style.color = "white";
Absatz.style.backgroundColor = "black";
}
//--></script>
</head>
<body>
<p id="Absatz">Text wechsle dich</p>

<form>
<input type="button" value="Normal" onclick="normal();" />
<input type="button" value="Invers" onclick="invers();" />
</form>
</body>
</html>

Ein häufig eingesetzter Effekt besteht darin, die CSS-Eigenschaft display zu setzen: Der Wert none beispielsweise blendet das dazugehörige Element ein oder aus; der davon belegte Platz wird freigegeben.

Wenn Sie mit Klassen arbeiten, benötigen Sie die style-Eigenschaft nicht, lediglich className. Damit haben Sie Lese- und Schreibzugriff auf die CSS-Klasse des jeweiligen Elements. Hier noch einmal das Beispiel mit dem invertierten Text, diesmal via CSS-Klassen:

<html>
<head>
<title>CSS</title>
<style type="text/css"><!--

.normal { color: black; background-color: white; }
.invers { color: white; background-color: black; }
--></style>

<script type="text/javascript"><!--
function setzeKlasse(klasse) {

var Absatz = document.getElementById("Absatz");
Absatz.className = klasse;
}

//--></script>
</head>
<body>
<p id="Absatz">Text wechsle dich</p>
<form>
<input type="button" value="Normal"
onclick="setzeKlasse('normal');" />
<input type="button" value="Invers"
onclick="setzeKlasse('invers');" />
</form>
</body>
</html>

JavaScript bietet noch einen viel detaillierteren Zugriff auf CSS-Stile, was aber in der Praxis eher seltener zum Einsatz kommt. Aus diesem Grund finden Sie hier nur einen kurzen Ausblick, was noch möglich ist:

gpBilder
 
Alle Stylesheets eines Dokuments (sowohl inline als auch externe Stile) stehen im Array document.styleSheets zur Verfügung. Mit der Eigenschaft disabled können sie aktiviert (false) und deaktiviert (true) werden.
gpBilder
 
Alle einzelnen CSS-Anweisungen innerhalb eines Stylesheets stehen im Array cssRules (Mozilla) bzw. rules (Internet Explorer). Der Zugriff erfolgt also via document.styleSheets[x].cssRules bzw. document.styleSheets[x].rules. Der Zugriff dort funktioniert dann wie bei regulären CSS-Stilen über die style-Eigenschaft, beispielsweise mit document.styleSheets[x].cssRules[y].style.backgroundColor oder document.styleSheets[x].rules[y].style. backgroundColor.

Für den Praxiseinsatz genügen aber in den allermeisten Fällen die Zugriffsmöglichkeiten auf die spezifischen Stile oder, noch besser, auf die CSS-Klassen.

 

 

17.3 HTML-Elemente 
topBilder
topBilder

Der Begriff DOM ist Ihnen ja bereits im vorherigen Kapitel begegnet: Document Object Model, die hierarchische Anordnung der einzelnen HTML-Dokumente im document-Objekt. Alles, was in Tags eingeschlossen ist, ist ein Objekt, also beispielsweise auch kursiv gedruckter Text (<i>-Tag). Auf jedes dieser Objekte kann man zugreifen, und jedes dieser Objekte hat eine Menge von Eigenschaften.

Prinzipiell genügt es, wenn man jedem Tag, auf das man mit JavaScript/DHTML zugreifen will, einen Identifikator gibt. Dazu verwenden Sie das id-Attribut:

<p id="Galileo">Galileo Press</p>

Ansonsten gibt es noch zwei Formen von Blöcken: <span> für ein Stück HTML oder Text ohne Umbruch davor und dahinter und <div> für HTML oder Text inklusive Umbruch davor und dahinter.

<div id="div1">
<!-- HTML-Kommandos etc. -->
</div>

Auch dem <div>- oder <span>-Tag kann man ein style-Attribut mitgeben, um beispielsweise den Inhalt des Blocks zu verstecken oder zu bewegen.

Alle Elemente einer HTML-Seite sind seit dem Internet Explorer 4 in document.all gespeichert. Über den Identifikator kann man dann auf ein Element zugreifen, um – und das ist das eigentlich Interessante – über die style-Eigenschaft des Elements Zugriff auf das Aussehen des Elements zu haben.

Mit dem folgenden Code macht man beispielsweise den Layer "div1" aus dem obigen Beispiel unsichtbar:

document.all.div1.style.visibility = "hidden";

Doch wieso haben wir im vorherigen Kapitel extra getElementById() und getElementsByTagName() eingeführt? Nun, document.all war ein Microsoft-Alleingang in der Browser-Version 4; seit der Browser-Version 5 gibt es auch im Internet Explorer die DOM-Methoden. Deswegen dient document.all nur noch der Browserunterscheidung, denn einige kleinere Unterschiede zwischen den Browsern gibt es weiterhin. Verwendet wird in allen Browsern getElementById().

Im folgenden Abschnitt sehen Sie zahlreiche Beispiele, die den Einsatz dieser Techniken demonstrieren. Davor aber noch ein praktischer Hinweis. Häufig geht es bei DHTML »lediglich« darum, Text in einem Textfeld auszugeben, oder darum, ganz allgemein irgendwo auf der Seite HTML-Code zu platzieren. An dieser Stelle kommt die JavaScript-Eigenschaft innerHTML ins Spiel, die genau das macht: HTML innerhalb eines Elements zu verändern.

Das folgende Listing demonstriert das an zwei Beispielen: per innerHTML wird sowohl ein Element einer Aufzählungsliste als auch Text innerhalb eines Absatzes erstellt:

<html>
<head>
<title>CSS</title>
<script type="text/javascript"><!--
window.onload = function() {
document.getElementById("Absatz").innerHTML =
"Neuer Text";
document.getElementById("Liste").innerHTML =
"<li>Neues Element</li>";
}
//--></script>
</head>
<body>

<p id="Absatz">Alter Text</p>
<ul id="Liste">

<li>Altes Element</li>
</ul>

</body>
</html>

In Abbildung 17.2 sehen Sie das Ergebnis: Die neuen Elemente und Texte erscheinen und überschreiben die alten.

Bilder

Abbildung 17.2     Der neue Text und das neue Element erscheinen.

 

 

17.4 Beispiele  

Die folgenden Beispiele demonstrieren die praktische Umsetzung des bisher Gesagten anhand einiger Beispiele, die Sie in ähnlicher Form auch auf diversen Websites finden können.


17.4.1 Animiertes Logo  

Unsere erste Anwendung soll eine einfache Animation sein. Ein Firmenlogo soll nicht nur statisch auf der Webseite stehen, sondern animiert werden. Beispielsweise soll es von links ins Bild schweben. Ein erstes HTML-Grundgerüst sieht folgendermaßen aus:

<html>
<head>
<title>Animiertes Logo</title>
</head>
<body>
<h1>Animiertes Logo</h1>
<img src="logo.gif" />
</body>
</html>

Die Animation des Logos geschieht nun folgendermaßen:

gpBilder
 
Das Logo wird in einen Block (<div>) eingefügt.
gpBilder
 
Die Positionierung dieses Blocks wird auf relative gesetzt.
gpBilder
 
Beim Laden der Seite wird der Block zuerst recht weit nach links bewegt.
gpBilder
 
Dann startet eine Animation, die das Logo stückweise nach rechts schiebt, bis es an seinem angestammten Platz ist.

Diese Liste soll nun abgearbeitet werden. Als Erstes muss der Layer mit relativer Positionierung eingefügt werden:

<html>
<head>
<title>Animiertes Logo</title>
</head>
<body onload="init();">
<h1>Animiertes Logo</h1>
<div id="logo" style="position:relative">

  <img src="logo.gif" /></div>
</body>
</html>

Als Nächstes muss die Funktion init() programmiert werden, die das Logo nach links verschiebt. Beim Mozilla steht die x-Koordinate der linken oberen Ecke eines Blocks in der Eigenschaft left und die y-Koordinate der linken oberen Ecke in der Eigenschaft top (und zwar relativ zum Browserfenster, Frame oder umgebenden Block). Da das Logo am Anfang nicht sichtbar sein soll, kann man hier einen negativen Wert angeben. Die ursprüngliche x-Koordinate wird in einer Variablen für später gespeichert.

Die Eigenschaften top und left sind keine numerischen Werte, sondern Strings. Sie enthalten Werte wie beispielsweise "200px" für 200 Pixel. Es macht dem JavaScript-Interpreter nichts aus, wenn Sie numerische Werte zuweisen – die Umwandlung geschieht automatisch –, aber wenn Sie wie im Beispiel mit den Werten rechnen möchten, müssen Sie sie zunächst in Integer-Werte umwandeln. Dies geht mit der Funktion parseInt().

Der Pferdefuß: Beim Internet Explorer heißen die Eigenschaften nicht left und top, sondern posLeft und posTop. Wie beim Mozilla auch befinden sich die Eigenschaften für die Position in der style-Eigenschaft des Elements.

Zunächst benötigen wir eine Browserunterscheidung. Ein Internet Explorer kann mit if (document.all) erkannt werden; alle anderen Browser müssen »nur« document.getElementById() unterstützen. Die Reihenfolge ist dabei essenziell: Da der Internet Explorer ebenfalls getElementById() unterstützen würde, darf die Fallunterscheidung nicht mit if (document.getElementById) beginnen.

Nun zurück zur Position des <div>-Elements: Diese beiden Hilfsfunktionen ermitteln und verändern die Block-Position in beiden großen Browserklassen:

function lieslinks() {
if (document.all) {
return document.all.logo.style.posLeft;
// oder: document.getElementById("logo").style.posLeft
} else if (document.getElementById) {
return parseInt(document.getElementById(
"logo").style.left);
}
}
function setzelinks(n) {
if (document.all) {
document.all.logo.style.posLeft = n;
} else if (document.getElementById) {
document.getElementById("logo").style.left = n +
"px";
}
}

Die Animation funktioniert so ähnlich wie bei der Laufschrift. Das Logo wird um (beispielsweise) drei Pixel nach rechts bewegt, und dann wird mit setTimeout() die Funktion nach einer gewissen Zeit wieder aufgerufen. Das Ganze wird so lange wiederholt, bis die (relative) Position der Grafik wieder gleich der ursprünglichen x-Koordinate ist, bis sie sich also wieder am anfänglichen Platz befindet.

In jedem Bearbeitungsschritt wird das Logo um drei Pixel nach rechts geschoben, sofern die relative Position kleiner als 0 ist (sofern sich das Logo also noch links von der ursprünglichen Position befindet). Ist die Position größer als 0, so ist das Logo ein wenig über das Ziel hinausgeschossen (in unserem Beispiel ist das der Fall, weil 200 nicht durch drei teilbar ist), und die Position wird korrigiert.

function init() {
if (document.getElementById) {
//Wenn moderner Browser
setzelinks(-200);
}
//Animation starten
animate();
}
function animate() {
if (lieslinks() > 0) {
setzelinks(0);
}
if (lieslinks() < 0) {
setzelinks(lieslinks() + 3);
setTimeout("animate()", 50);
}
}

Das vollständige Listing sieht dann so aus:

<html>
<head>
<title>Animiertes Logo</title>
<script type="text/javascript"><!--
function lieslinks() {
if (document.all) {
return document.all.logo.style.posLeft;
} else if (document.getElementById) {
return parseInt(
document.getElementById("logo").style.left);
}
}
function setzelinks(n) {
if (document.all) {
document.all.logo.style.posLeft = n;
} else if (document.getElementById) {
document.getElementById("logo").style.left = n +
"px";
}
}
function init() {
if (document.getElementById) {
//Wenn moderner Browser
setzelinks(-200);
}
//Animation starten
animate();
}
function animate() {
if (lieslinks() > 0) {
setzelinks(0);
}
if (lieslinks() < 0) {
setzelinks(lieslinks() + 3);
setTimeout("animate()", 50);
}
}
//--></script>
</head>
<body onload="init();">
<h1>Animiertes Logo</h1>
<div id="logo" style="position:relative">
<img src="logo.gif" />
</div>
</body>
</html>

AbbildungBilder

Hier klicken, um das Bild zu Vergrößern

Abbildung 17.3     Das Logo bewegt sich, gemäß dem Galileo-Leitspruch


17.4.2 Sichtbar und unsichtbar  

Von besonderem Interesse ist noch die Möglichkeit, Blockelemente sichtbar oder unsichtbar zu machen. Man kann sogar Elemente übereinander anordnen und deren (virtuelle) z-Koordinate setzen, aber das geht über dieses Beispiel hinaus. Als Beispielanwendung soll eine Art Registersystem programmiert werden, wie man es von Windows-Applikationen her kennt. In diesem Beispiel gibt es drei Register, und nach einem Klick auf die Registerreiter soll das entsprechende Register angezeigt werden.

Hierzu ist Folgendes zu tun:

gpBilder
 
Die drei Register werden im HTML-Code definiert und alle an dieselbe Stelle gesetzt.
gpBilder
 
Das erste Register wird sichtbar gemacht (bzw. bleibt sichtbar), die anderen beiden werden unsichtbar.
gpBilder
 
Wird ein Reiter angeklickt, so wird das aktuelle Register unsichtbar gemacht und das ausgewählte Register angezeigt.

Wir beginnen mit dem HTML-Code. Beachten Sie, dass dort noch nicht alle Register an dieselbe Stelle gesetzt werden (das wäre mit dem style-Attribut kein Problem); stattdessen wird später mit JavaScript die Position des ersten Registers bestimmt, und die anderen beiden werden dann dorthin bewegt. Bei den drei Reitern ist aber schon die JavaScript-Funktion zum Ein- bzw. Ausblenden der jeweiligen Register vorgesehen.

<html>
<head>
<title>Register</title>
<style text="text/css"><!--
a {color:black; text-decoration:none}
--></style>
</head>
<body onload="init();">
<table><tr>
<td bgcolor="red">
<a href="javascript:register(1)">Register _fcksavedurl="javascript:register(1)">Register 1</a>
</td>
<td bgcolor="green">
<a href="javascript:register(2)">Register 2</a>
</td>
<td bgcolor="blue">
<a href="javascript:register(3)">Register 3</a>
</td>
</tr></table>
<div id="register1" style="position:absolute">
<h3>Register 1</h3>
</div>
<div id="register2" style="position:absolute">
<h3>Register 2</h3>
</div>
<div id="register3" style="position:absolute">
<h3>Register 3</h3>
</div>
</body>
</html>

Die Implementierung ist klar: Die CSS-Eigenschaft visibility wird gesetzt, um die einzelnen Register ein- und auszublenden. Zwar könnte man hier mit einer Zeichenkette und eval() arbeiten (wie schon einige Male zuvor in diesem Buch), aber es ist praktischer, in einer Variablen eine Referenz auf das Objekt zu speichern. Man kann dann auf die visibility-Eigenschaft mittels Objektreferenz.visibility zugreifen und spart sich alle weiteren Abfragen.

Die Variablendefinition sieht wie folgt aus:

if (document.getElementById) {
var objref1 =
document.getElementById("register1").style;
var objref2 =
document.getElementById("register2").style;
var objref3 =
document.getElementById("register3").style;
}

Der nächste Schritt erstellt wieder ein paar Hilfsfunktionen, um die Koordinaten eines Blocks browserunabhängig zu setzen:

function lieslinks(n) {
eval("var obj = objref" + n);
if (document.all) {
return obj.posLeft;
} else if (document.getElementById) {
return parseInt(obj.left);
}
}
function setzelinks(n, wert) {
eval("var obj = objref" + n);
if (document.all) {
obj.posLeft = wert;
} else if (document.getElementById) {
obj.left = wert + "px";
}
}
function liesoben(n) {
eval("var obj = objref" + n);
if (document.all) {
return obj.posTop;
} else if (document.getElementById) {
return obj.top;
}
}
function setzeoben(n, wert){
eval("var obj = objref" + n);
if (document.all) {
obj.posTop = wert;
} else if (document.getElementById) {
obj.top = wert + "px";
}
}

Anstelle von eval() können Sie natürlich auch – etwas eleganter – alle Objektreferenzen in einem Array speichern.

Die Funktion init() wird beim Laden der Seite ausgeführt. Dort werden zunächst das zweite und dritte Register neu positioniert, und zwar an derselben Stelle wie das erste Register. Außerdem müssen die beiden Register unsichtbar gemacht werden, denn anfangs ist das erste Register sichtbar:

var layer_x = lieslinks(1);
var layer_y = liesoben(1);
setzelinks(2, layer_x);
setzeoben(2, layer_y);
objref2.visibility = "hidden";
setzelinks(3, layer_x);
setzeoben(3, layer_y);
objref3.visibility = "hidden";

Das war es auch fast schon. Das Einzige, was noch fehlt, ist die Funktion register(), die von den JavaScript-Links aufgerufen wird und das jeweils gewählte Register einblendet und die anderen unsichtbar macht:

function register(n) {
for (var i=1; i<=3; i++) {
var visi = (i==n) ? "visible" : "hidden";
document.layers["register"+i].visibility = visi;
}
}

Hier der komplette, browserunabhängige Code für dieses Beispiel:

<html>
<head>
<title>Register</title>
<style type="text/css"><!--
a {color:black; text-decoration:none}
--></style>
<script type="text/javascript"><!--
var objref1;
var objref2;
var objref3;
function lieslinks(n) {
eval("var obj = objref" + n);
if (document.all) {
return obj.posLeft;
} else if (document.getElementById) {
return parseInt(obj.left);
}
}
function setzelinks(n, wert) {
eval("var obj = objref" + n);
if (document.all) {
obj.posLeft = wert;
} else if (document.getElementById) {
obj.left = wert;
}
}
function liesoben(n) {
eval("var obj = objref" + n);
if (document.all) {
return obj.posTop;
} else if (document.getElementById) {
return obj.top;
}
}
function setzeoben(n, wert){
eval("var obj = objref" + n);
if (document.all) {
obj.posTop = wert;
} else if (document.getElementById) {
obj.top = wert;
}
}

function init() {
if (document.getElementById) {
objref1 =
document.getElementById("register1").style;
objref2 =
document.getElementById("register2").style;
objref3 =
document.getElementById("register3").style;
}


var layer_x = lieslinks(1);
var layer_y = liesoben(1);
setzelinks(2, layer_x);
setzeoben(2, layer_y);
objref2.visibility = "hidden";
setzelinks(3, layer_x);
setzeoben(3, layer_y);
objref3.visibility = "hidden";
}
function register(n) {
for (var i=1; i<=3; i++) {
var visi = (i==n) ? "visible" : "hidden";
eval("var obj = objref" + i);
obj.visibility = visi;
}
}
//--></script>
</head>
<body onload="init();">
<table><tr>
<td bgcolor="red">
<a href="javascript:register(1)">Register _fcksavedurl="javascript:register(1)">Register 1</a>
</td>
<td bgcolor="green">
<a href="javascript:register(2)">Register 2</a>
</td>
<td bgcolor="blue">
<a href="javascript:register(3)">Register 3</a>
</td>
</tr></table>
<div id="register1" style="position:absolute">
<h3>Register 1</h3>
</div>
<div id="register2" style="position:absolute">
<h3>Register 2</h3>
</div>
<div id="register3" style="position:absolute">
<h3>Register 3</h3>
</div>
</body>
</html>

Bilder

Abbildung 17.4     Immer nur ein Register ist sichtbar.


17.4.3 Neuer Mauszeiger  

Ein Effekt, der sich auf vielen privaten Websites befindet, ist die Verwendung eines neuen Mauszeigers. Natürlich ist es nicht möglich, die Anzeigeeigenschaften für den Mauszeiger des Benutzers zu ändern, das wäre allein aus Sicherheitsgründen eine Katastrophe, aber es ist möglich, ein Element zu erstellen, der sich immer an der aktuellen Mauszeigerposition befindet und somit die Maus des Benutzers verfolgt. Als Beispielgrafik verwenden wir – wie zuvor auch – das Logo von Galileo Press. Sie finden es im Internet unter http://www.galileo-press.de/download/images/galileo_press.gif – aber Sie können auch eine beliebige andere Grafik verwenden. Die folgenden Schritte müssen umgesetzt werden, damit dies funktioniert:

gpBilder
 
Das Element mit der Grafik wird im HTML-Code definiert (mit id="mauszeiger").
gpBilder
 
Wenn der Benutzer eine Mausbewegung macht (Event-Handler onmousemove), wird das Element an die aktuelle Mausposition bewegt.

Wie bereits in Kapitel 14 beschrieben wurde, funktioniert das Event-Handling in den »großen« Browsern leicht unterschiedlich. Mit dem folgenden Code, der in der schon standardmäßig verwendeten Funktion init() landet, fangen Sie Mausbewegungen ab und weisen JavaScript an, bei jeder Bewegung die Funktion anim() aufzurufen:

function init() {
if (window.Event) {
document.captureEvents(Event.MOUSEMOVE);
}
document.onmousemove = anim;
}

Die Funktion anim() platziert dann den Mauszeiger und verwendet dabei zwei schon bekannte Hilfsfunktionen:

function setzelinks(n) {
if (document.all) {
document.all.mauszeiger.style.posLeft = n;
} else if (document.getElementById) {
document.getElementById("mauszeiger").style.left =
n + "px";
}
}
function setzeoben(n) {
if (document.all) {
document.all.mauszeiger.style.posTop = n;
} else if (document.getElementById) {
document.getElementById("mauszeiger").style.top =
n + "px";
}
}

Doch nun zur Funktion anim() selbst. Diese ermittelt zunächst die aktuelle Mausposition. In Mozilla-Browsern erhalten Sie diese via e.pageX und e.pageY (e ist der Parameter, der automatisch an die Ereignisbehandlungsfunktion übergeben wird). Im Internet Explorer verwenden Sie event.clientX und event.clientY. Dann platzieren Sie – mit setzelinks() und setzeoben() – die Maus an der angegebenen Position:

function anim(e) {
var x = (window.Event) ? e.pageX : event.clientX;
var y = (window.Event) ? e.pageY : event.clientY;
setzelinks(x);
setzeoben(y);
}

Hier noch einmal der komplette Code im Überblick:

<html>
<head>
<title>Mauszeiger</title>
<script type="text/javascript"><!--
function init() {
if (window.Event) {
document.captureEvents(Event.MOUSEMOVE);
}
document.onmousemove = anim;
}
function setzelinks(n) {
if (document.all) {
document.all.mauszeiger.style.posLeft = n;
} else if (document.getElementById) {
document.getElementById("mauszeiger").style.left =
n + "px";
}
}
function setzeoben(n) {
if (document.all) {
document.all.mauszeiger.style.posTop = n;
} else if (document.getElementById) {
document.getElementById("mauszeiger").style.top =
n + "px";
}
}
function anim(e) {
var x = (window.Event) ? e.pageX : event.clientX;
var y = (window.Event) ? e.pageY : event.clientY;
setzelinks(x);
setzeoben(y);
}
//--></script>
</head>
<body bgcolor="white" onload="init();">
<h1>Mauszeiger</h1>
<div id="mauszeiger" style="position:absolute">
<img src="logo.gif" />
</div>
</body>
</html>

Bilder

Abbildung 17.5     Ein neuer (und ziemlich großer) Mauszeiger


17.4.4 Permanentes Werbebanner 
topBilder

Gratis-Hoster, also Firmen, die kostenlosen Webspace anbieten, lassen sich ja einiges einfallen, um effektiv Werbung auf den Webseiten unterzubringen. Ein besonders aufdringlicher Gag ist ein Werbebanner, das so konzipiert ist, dass es immer sichtbar ist (beispielsweise, indem es sich immer in der rechten oberen Ecke des Browserfensters befindet). Eine weitere Anwendungsmöglichkeit hierfür ist eine Navigation oder Sitemap, die ebenfalls immer sichtbar ist. Auch hier gilt: Setzen Sie den Effekt recht sparsam ein, oder bieten Sie zumindest die Möglichkeit an, das Banner (oder die Sitemap) ausblenden zu können, um die dahinter liegenden Bereiche auf der Website überhaupt ansehen zu können.

Die Vorgehensweise bei diesem Beispiel ist folgende:

gpBilder
 
Im HTML-Code wird ein Element definiert, der das Banner enthält (mit id="logo", wir verwenden auch in diesem Beispiel wieder das Galileo-Logo, das hier die Funktion eines Werbelinks auf die Verlags-Homepage hat).
gpBilder
 
Per Timeouts wird das Element alle halbe Sekunde in die rechte obere Ecke des Browserfensters verschoben.

Auch hier beginnen wir mit einer Funktion init(). Da wir mit Timeouts arbeiten, müssen wir an dieser Stelle nicht mühsam Ereignisse abfangen und umleiten, sondern lediglich das Werbebanner sichtbar machen. (Es wäre nicht hübsch, wenn das Banner schon beim Laden der Seite sichtbar wäre, denn zu diesem Zeitpunkt ist es noch recht schwierig, die richtige Position zu bestimmen.) Dann rufen wir die Funktion auf, die das Logo in die rechte Ecke schiebt (anim()):

function init() {
if (document.getElementById) {
document.getElementById("logo").style.visibility =
"visible";
}
anim();
}

Auch die Funktion anim() ist relativ kurz, der Aufwand besteht – wie so oft bei DHTML – eher in der Recherche (und in der Fehlersuche) als in der Programmierung per se. Beginnen wir mit Mozilla-Browsern: In window.pageXOffset und window.pageYOffset steht, an welche Position die aktuelle Seite im Browserfenster gescrollt worden ist. Die Y-Koordinate der linken oberen Ecke des Banners muss also auf window.pageYOffset gesetzt werden, das Banner soll ja oben andocken. Bei der X-Koordinate ist das nicht ganz so trivial, aber nicht unmöglich. Also: In window.innerWidth steht, wie breit das Browserfenster abzüglich Scrollbalken, Leisten etc. ist. In der Praxis ist dieser Wert nicht immer exakt ganz zutreffend, aber man erhält immerhin eine ganz gute Schätzung. Von diesem Wert muss man die Breite der Grafik abziehen (oder am besten noch ein bisschen mehr, eben wegen der Ungenauigkeiten mancher Browser), und dann hat man die Position der Grafik – beinahe. Schließlich ist es auch möglich, auf Webseiten horizontal zu scrollen, also muss zu diesem Wert noch window.pageXOffset addiert werden.

Jedoch heißen die Eigenschaften, die beispielsweise die aktuelle Scrollposition des Browserfensters enthalten, beim Internet Explorer komplett anders als bei Mozilla. Aus window.innerWidth (Breite des Browserfensters) wird document.body.clientWidth, und window.pageXOffset und window.pageYOffset finden in document.body.scrollLeft und document.body.scrollTop ihre Entsprechung. Der Rest bleibt beinahe identisch. Ein kleiner Unterschied am Rande: document.body.clientWidth arbeitet viel exakter als das Mozilla-Pendant. Man muss von diesem Wert also in der Tat nur die Breite der Grafik abziehen und nicht etwas mehr, wie das zuvor noch der Fall war.

Somit sind die Koordinaten ermittelt worden, und Sie müssen nur noch dafür sorgen, dass sich anim() via Timeout wieder selbst aufruft – oder Sie verwenden gleich setInterval() anstelle von setTimeout().

function anim() {
if (document.all) {
var x = document.body.clientWidth +
document.body.scrollLeft – 181;
var y = document.body.scrollTop;
} else if (document.getElementById) {
var x = window.innerWidth + window.pageXOffset -
192;
var y = window.pageYOffset;
}
setzelinks(x);
setzeoben(y);
setTimeout("anim()", 500);
}

Die Funktionen setzelinks() und setzeoben() kennen Sie bereits von den vorherigen Beispielen zur Genüge, weswegen Sie im Folgenden ohne weitere Vorrede den kompletten Code finden:

<html>
<head>
<title>Werbebanner</title>
<script type="text/javascript"><!--
function init() {
if (document.getElementById) {
document.getElementById("logo").style.visibility =
"visible";
}
anim();
}
function setzelinks(n) {
if (document.all) {
document.all.logo.style.posLeft = n;
} else if (document.getElementById) {
document.getElementById("logo").style.left = n + "px";
}
}
function setzeoben(n) {
if (document.all) {
document.all.logo.style.posTop = n;
} else if (document.getElementById) {
document.getElementById("logo").style.top = n + "px";
}
}
function anim() {
if (document.all) {
var x = document.body.clientWidth +
document.body.scrollLeft – 181;
var y = document.body.scrollTop;
} else if (document.getElementById) {
var x = window.innerWidth + window.pageXOffset -
192;
var y = window.pageYOffset;
}
setzelinks(x);
setzeoben(y);
setTimeout("anim()", 500);
}
//--></script>
</head>
<body bgcolor="white" onload="init();">
<h1>Werbebanner</h1>
<div id="logo"
style="visibility:hide;position:absolute">
<a href="http://www.galileo-press.de/"><img _fcksavedurl="http://www.galileo-press.de/"><img src="logo.gif" border="0" /></a>
</div>
<script type="text/javascript"><!--
for (var i=0; i<30; i++) {
document.write("F&uuml;lltext");
}
for (i=0; i<3; i++) {
for (var j=0; j<10; j++) {
document.write("<" + "br" + " />");
}
document.write("F&uuml;lltext");
}
//--></script>
</body>
</html>

Zum Ende dieses Kapitels noch ein kurzer Ausblick: Die Möglichkeiten von DHTML sind fast unendlich. An dieser Stelle kann leider kein ausführlicher Einstieg in die Materie gegeben werden, da dies den Umfang dieses Buches sprengen würde und ja auch nicht unser eigentliches Thema ist. Aus demselben Grund können hier auch nicht alle Inkompatibilitäten der verschiedenen Browser aufgelistet werden. Das Ziel dieses Kapitels war es, Ihnen einen browserunabhängigen Überblick über alle relevanten Aspekte der Materie zu geben. Mit den vorgestellten Techniken, der Referenz und ein wenig Fantasie und Freude am Ausprobieren können Sie beeindruckende Ergebnisse erzielen. Mehr brauchen Sie in der Regel sowieso nicht.

Bilder

Abbildung 17.6     Das Werbebanner ist immer rechts oben auf der Seite.

Das Tutorial ist ein Auszug aus dem Buch von Stefan Münz:

Professionelle Websites - Programmierung, Design und Administration von Webseiten
Addison-Wesley, 2. Auflage, 1136 Seiten, gebunden, komplett in Farbe, mit DVD

Die Veröffentlichung des Kapitels erfolgt mit freundlicher Genehmigung von
Pearson Education.

Mehr Informationen zu diesem wunderbaren Fachbuch für Webmaster und Webentwickler
gibt es hier: Professionelle Websites

Alle Teile des Buches: 

1 Intro
2 HTML und CSS
3 Dynamische Seiten mit JavaScript/DOM
4 Die Server-Seite
5 PHP und MySQL
6 XML
7 Betrieb von Websites
8 Referenz
Bilder

Kommentare
Achtung: Du kannst den Inhalt erst nach dem Login kommentieren.
Portrait von tanzfrosch
  • 11.01.2018 - 14:56

Dankeschön, tolles Tut. !

Portrait von MaoMao
  • 09.01.2013 - 16:58

Gute Tutorial leicht erklärt.

Portrait von odin11
  • 29.04.2008 - 16:43

habe die Vorlage genutzt und sie lässt sich auch mit einigen Abänderungen gut anpassen.

Finde Vorlagen überhaupt super, da mir die Zeit fehlt, selber welche zu erstellen.

merci

x
×
×