Kapitel 17 DHTML II: Internet Explorer
Ist es ein Fortschritt, wenn ein Kannibale
Messer und Gabel benutzt?
– Lec
Wie bereits im vorherigen Kapitel erwähnt, ist die CSS-Unterstützung des Internet Explorer weitaus vollständiger als die des Netscape Navigator. Aus diesem Grund stehen die Chancen auch ganz gut, dass der Netscape Navigator 6 dieselbe Syntax unterstützen wird wie der Internet Explorer. Doch leider gibt es an den entscheidenden Stellen große Unterschiede, sodass zum heutigen Zeitpunkt (Frühjahr 2001) die wenigsten DHTML-Seiten mit dem Netscape 6 konform gehen. Sie sind nach der Lektüre des nächsten Kapitels in der Lage, diesen Missstand zu beheben, doch zunächst wird in diesem Kapitel der Einsatz von DHTML für den Internet Explorer in den Versionen 4, 5 und 5.5 demonstriert. Wie bereits im vorangegangenen Kapitel versprochen, werden im übernächsten Kapitel Strategien vorgestellt, um die Beispiele browser-unabhängig zu machen. In diesem Kapitel werden die Beispiele, die zuvor für den Netscape Navigator implementiert worden sind, für den Internet Explorer
umgeschrieben. Die Beschreibung der Algorithmen fällt also ein wenig kürzer aus. Vom Prinzip her ist ja alles bekannt, es werden nur die technischen Hintergründe (wie man auf welche Objekte zugreift) erläutert.

17.1 Grundlagen  
Der Begriff DOM wird Ihnen in Ihrer Laufbahn als JavaScript-Programmierer noch öfter begegnen. Diese Abkürzung steht für Document Object Model, und darunter versteht man die hierarchische Anordnung der einzelnen HTML-Dokumente im document-Objekt. Im Gegensatz zum Netscape Navigator 4 ist im Internet Explorer alles, was zwischen Tags eingeschlossen 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. Somit benötigt man bei Grafiken (<IMG>-Tag) keinen Link um die Grafiken, um einen Mouseover-Effekt zu erzielen, dem <IMG>-Tag kann auch ein Event-Handler mitgegeben werden.
17.1.1 HTML-Tags  
Prinzipiell genügt es, wenn man jedem Tag, auf den man mit JavaScript/DHTML zugreifen will, einen Identifikator gibt. Dazu verwenden Sie, wie beim Netscape Navigator auch, den ID-Parameter:
<P ID="Galileo">Galileo Press</P>
So etwas wie ein Layer hat sich aber schon zuvor als sehr nützlich erwiesen. Es gibt einen Tag, der sogar – man glaubt es kaum – vom Netscape Navigator unterstützt wird: <DIV>. Es wird wie bei einem Layer angewendet, nur kann man keine externen Dateien einbinden.
<DIV ID="DIV1">
<!-- HTML-Kommandos etc. -->
</DIV>
Auch dem <DIV>-Tag kann man einen STYLE-Parameter mitgeben, um beispielsweise den Inhalt des <DIV>-Tags zu verstecken oder zu bewegen.
17.1.2 Objektzugriff  
Alle Elemente einer HTML-Seite sind beim 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"
Sie sehen an der Punkt-Schreibweise, dass Sie keine Leerzeichen oder Sonderzeichen im ID-Parameter für Ihre <DIV>-Tags verwenden sollten.
An diesem Beispiel sehen Sie auch eine recht einfache Überprüfung, ob der Browser den Zugriff auf Elemente im Internet Explorer-Stil unterstützt (momentan tun das nur der Internet Explorer Version 4 und 5.x). Wie schon früher verwenden wir die Methode, die das Vorhandensein eines Objekts prüft:
if (document.all){
//Code für Internet Explorer 4/5
}
17.2 Beispiele  
Die Beispiele aus dem vorherigen Kapitel werden im Folgenden für den Internet Explorer umgeschrieben. Galt zuvor noch, dass alle Beispiele lediglich mit dem Netscape Naviagor 4 problemlos funktionieren, so gilt hier dasselbe für die Internet Explorer-Versionen 4 und 5.
17.2.1 Animiertes Logo  
Wir beginnen mit dem animierten Logo. Zunächst muss der HTML-Code von <LAYER> auf <DIV> geändert werden:
<HTML>
<HEAD>
<TITLE>Animiertes Logo</TITLE>
</HEAD>
<BODY onLoad="init()">
<H3>Animiertes Logo</H3>
<DIV ID="logo" STYLE="position:relative"><IMG SRC="logo.gif"></DIV>
</BODY>
</HTML>
Der <DIV>-Tag hat den großen Vorteil, dass – bei relativer Positionierung – die x- und y-Koordinate der linken oberen Ecke gleich Null ist, was das Skript ein wenig vereinfacht. Der Pferdefuß: Beim Internet Explorer heißen die Eigenschaften nicht left und top, sondern posLeft und posTop. Ansonsten muss man im Vergleich zum Netscape Navigator-Skript lediglich den Zugriff auf document.all ändern. Der Aufwand hält sich derart in Grenzen, dass hier gleich die Endversion des Skripts angegeben wird.
<HTML>
<HEAD>
<TITLE>Animiertes Logo</TITLE>
<SCRIPT LANGUAGE="JavaScript"><!--
function init(){
if (document.all)
document.all.logo.style.posLeft = -200
//Animation starten
animate()
}
function animate(){
if (document.all.logo.style.posLeft>0)
document.all.logo.style.posLeft = 0
if (document.all.logo.style.posLeft<0){
document.all.logo.style.posLeft += 3
setTimeout("animate()", 50)
}
}
//--></SCRIPT>
</HEAD>
<BODY onLoad="init()">
<H3>Animiertes Logo</H3>
<DIV ID="logo" STYLE="position:relative"><IMG SRC="logo.gif"></DIV>
</BODY>
</HTML>
Abbildung 17.1 Das Logo fliegt von links ein.
|
17.2.2 Drag&Drop  
Auch das Drag&Drop-Beispiel lässt sich mit recht wenig Aufwand umschreiben. Die Änderungen sind ein wenig komplizierter als beim vorherigen Beispiel, weil die Ereignisbehandlung beim Internet Explorer ja etwas anders abläuft. Während beim Netscape Navigator noch mit capture Events() gearbeitet werden musste, unterstützt der Internet Explorer das Bubbling-Prinzip, was den Aufwand etwas verringert. Die Initialisierungsfunktion init() fällt deswegen etwas kürzer aus als beim Netscape-Pendant: Als weitere Anpassung müssen – beim Auslesen der Koordinaten des Logos – die Zugriffe auf das Objekt angepasst werden.
var logo_x, logo_y
function init(){
document.onmousedown = setzestatus
document.onmouseup = setzestatus
document.onmousemove = dragdrop
logo_x = document.all.logo.style.posLeft
logo_y = document.all.logo.style.posTop
}
Als Nächstes müssen Sie sich die Funktion setzestatus() vornehmen. Beim Netscape Navigator wurde das auslösende Ereignis als Parameter übergeben, beim Internet Explorer steht das bekannterweise im Objekt event. Außerdem müssen wiederum die Zugriffe auf die Koordinaten des Logos aktualisiert werden. Die aktuellen Koordinaten der Maus beim Eintreten eines Ereignisses erhält man beim Internet Explorer über die Ereigniseigenschaften clientX und clientY.
var bereit = false
var maus_x, maus_y
function setzestatus(){
if (event.type=="mouseup" || (event.type=="mousedown" &&
event.srcElement.name=="logogfx")){
maus_x = event.clientX
maus_y = event.clientY
bereit = !bereit
if (event.type=="mousedown"){
logo_x = document.all.logo.style.posLeft
logo_y = document.all.logo.style.posTop
}
}
}
Die letzte JavaScript-Funktion, die noch angepasst werden muss, ist dragdrop(). Hier geschieht aber wirklich nichts Neues mehr, nur der Zugriff auf das Ereignis sowie die Koordinaten wird wie gehabt umgeschrieben:
function dragdrop(){
if (bereit){
var aktuell_x = event.clientX
var aktuell_y = event.clientY
document.all.logo.style.posLeft = logo_x +
aktuell_x – maus_x
document.all.logo.style.posTop = logo_y +
aktuell_y – maus_y
}
}
Im Folgenden sehen Sie noch einmal das komplette Beispiel zum Abtippen. Im HTML-Code wurde der Layer durch einen <DIV>-Tag ersetzt. Wenn Sie den Code nicht abtippen wollen, was gut zu verstehen ist, da er eine gewisse Länge hat, finden Sie ihn auch auf der Buch-CD-ROM.
<HTML>
<HEAD>
<TITLE>Drag & Drop</TITLE>
<SCRIPT LANGUAGE="JavaScript"><!--
var logo_x, logo_y
function init(){
document.onmousedown = setzestatus
document.onmouseup = setzestatus
document.onmousemove = dragdrop
logo_x = document.all.logo.style.posLeft
logo_y = document.all.logo.style.posTop
}
var bereit = false
var maus_x, maus_y
function setzestatus(){
if (event.type=="mouseup" || (event.type=="mousedown" &&
event.srcElement.name=="logogfx")){
maus_x = event.clientX
maus_y = event.clientY
bereit = !bereit
if (event.type=="mousedown"){
logo_x = document.all.logo.style.posLeft
logo_y = document.all.logo.style.posTop
}
}
}
function dragdrop(){
if (bereit){
var aktuell_x = event.clientX
var aktuell_y = event.clientY
document.all.logo.style.posLeft = logo_x + aktuell_x – maus_x
document.all.logo.style.posTop = logo_y + aktuell_y – maus_y
}
}
//--></SCRIPT>
</HEAD>
<BODY onLoad="init()">
<H3>Drag & Drop</H3>
<DIV ID="logo" STYLE="position:relative"><IMG SRC="logo.gif"></DIV>
</BODY>
</HTML>
Abbildung 17.2 Das Logo wurde per Drag&Drop nach rechts unten verschoben.
|
Sie werden beim Testen bemerken, dass das Drag&Drop in der Praxis nicht so einfach funktioniert. Der Browser reagiert nämlich, wenn Sie die Maustaste drücken und die Maus dann bewegen, als ob Sie Text markieren wollten. Das System ist also noch nicht perfekt. Ein Ausweg wäre, durch einen Mausklick das Drag&Drop einzuschalten und durch einen weiteren Klick es wieder auszuschalten. Die Funktion setzestatus() müsste dazu immer beim Eintritt des click-Ereignisses aufgerufen werden, und man müsste sich von mouseup und mousedown verabschieden. Sie können das zur Übung einmal ausprobieren, der Arbeitsaufwand ist minimal.
17.2.3 Sichtbar und unsichtbar  
Es folgt das Beispiel mit den an Windows-Applikationen angelehnten Registern. Hier gestalten sich die Änderungen aber besonders einfach, vor allem dann, wenn Sie die vorherigen Beispiele schon durchgearbeitet haben. Sie müssen lediglich Zugriffe auf das <DIV>-Element durchführen und die visibility-Eigenschaft ändern. Aus diesem Grund folgt hier gleich der gesamte Code, Änderungen sind wie immer fett gesetzt.
<HTML>
<HEAD>
<TITLE>Register</TITLE>
<STYLE TEXT="text/css"><!--
A color:black; text-decoration:none}
--></STYLE>
<SCRIPT LANGUAGE="JavaScript"><!--
function init(){
var layer_x = document.all.register1.style.posLeft
var layer_y = document.all.register1.style.posTop
document.all.register2.style.posLeft = layer_x
document.all.register2.style.posTop = layer_y
document.all.register2.style.visibility = "hidden"
document.all.register3.style.posLeft = layer_x
document.all.register3.style.posTop = layer_y
document.all.register3.style.visibility = "hidden"
}
function register(n){
for (var i=1; i<=3; i++){
var visi = (i==n) ? "visible" : "hidden"
document.all("register"+i).style.visibility = visi
}
}
//--></SCRIPT>
</HEAD>
<BODY onLoad="init()">
<TABLE><TR>
<TD BGCOLOR="red">
<A HREF="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:relative">
<H3>Register 1</H3>
</DIV>
<DIV ID="register2" STYLE="position:relative">
<H3>Register 2</H3>
</DIV>
<DIV ID="register3" STYLE="position:relative">
<H3>Register 3</H3>
</DIV>
</BODY>
</HTML>
Abbildung 17.3 Registerreiter mit DHTML
|
Sie sehen hier einen weiteren Unterschied zum Netscape Navigator. Wenn man beim Navigator den Identifikator eines Layers nicht angeben will, kann man mit document.layers["Name"] darauf zugreifen, also mit eckigen Klammern. Beim Internet Explorer muss man runde Klammern verwenden, also document.all("Name"). Kleine Frage am Rande: Wie kann man das ohne Klammern erledigen? Kleiner Tipp: Hier hilft eval() weiter.
17.2.4 Neuer Mauszeiger  
Das Beispiel mit dem Mauszeiger bringt kaum etwas Neues, sodass Sie an dieser Stelle auch nur den Code wieder finden, mit hervorgehobenen Änderungen. Die Ereignisbehandlung ist eine andere, und die Koordinaten von Layer und Mauszeiger werden auf eine andere Art und Weise ermittelt, ansonsten keine großen Besonderheiten. Sie sollten lediglich darauf achten, absolute Positionierung zu verwenden, denn sonst ist das Galileo-Logo ein wenig zur Seite versetzt (da es sich beim Laden der Seite nicht in der linken oberen Ecke befand).
Abbildung 17.4 Das Galileo-Logo als Mauszeiger
|
<HTML>
<HEAD>
<TITLE>Mauszeiger</TITLE>
<SCRIPT LANGUAGE="JavaScript"><!--
function init(){
document.onmousemove=anim
}
function anim(e){
document.all.mauszeiger.style.posLeft = event.clientX
document.all.mauszeiger.style.posTop = event.clientY
}
//--></SCRIPT>
</HEAD>
<BODY BGCOLOR="white" onLoad="init()">
<H1>Mauszeiger</H1>
<DIV ID="mauszeiger" STYLE="position:absolute">
<IMG SRC="logo.gif"></DIV>
</BODY>
</HTML>
17.2.5 Permanentes Werbebanner  
Das Umschreiben des Beispiels mit dem immer sichtbaren Werbebanner ist ein wenig aufwendiger als der grafische Mauszeiger, deswegen Schritt für Schritt. Das ID-Attribut des <DIV>-Tags, der das Werbebanner umschließt, ist wieder logo. In der Funktion init() wird der Layer sichtbar gemacht, und anim() aufgerufen:
function init(){
document.all.logo.style.visibility="visible"
anim()
}
In der Funktion anim() wird wie zuvor die neue Position des Werbebanners berechnet, das Banner dorthin verschoben, und dann die Funktion via Timeout nach einer halben Sekunde erneut aufgerufen. Jedoch heißen die Eigenschaften, die beispielsweise die aktuelle Scrollposition des Browserfensters enthalten, beim Internet Explorer (und wohl auch beim Netscape 6) komplett anders als beim Netscape Navigator 4. 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. Kleiner Unterschied am Rande: document.body. clientWidth arbeitet
viel exakter als das Netscape-Pendant, man muss von diesem Wert also in der Tat nur die Breite der Grafik abziehen, und nicht etwas mehr, wie das noch beim Netscape Navigator 4 der Fall war.
function anim(){
document.all.logo.style.posLeft = document.body.clientWidth +
document.body.scrollLeft – 89
document.all.logo.style.posTop = document.body.scrollTop
setTimeout("anim()", 500)
}
Abbildung 17.5 Das Galileo-Logo als immer sichtbares Werbebanner
|
Zum Abschluss dieses Beispiels (und dieses Kapitels) noch einmal das komplette Listing wie Sie es auf der Buch-CD finden.
<HTML>
<HEAD>
<TITLE>Werbebanner</TITLE>
<SCRIPT LANGUAGE="JavaScript"><!--
function init(){
document.all.logo.style.visibility="visible"
anim()
}
function anim(){
document.all.logo.style.posLeft = document.body.clientWidth +
document.body.scrollLeft – 89
document.all.logo.style.posTop=document.body.scrollTop
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 SRC="logo.gif" BORDER="0"></A>
</DIV>
<SCRIPT LANGUAGE="JavaScript"><!--
for (var i=0; i<30; i++)
document.write("Fülltext")
for (i=0; i<3; i++){
for (var j=0; j<10; j++)
document.write("<"+"BR"+">")
document.write("Fülltext")
}
//--></SCRIPT>
</BODY>
</HTML>
17.3 Fragen & Aufgaben  
1. |
Gehen Sie zu dem Beispiel mit den zwei verschachtelten Layern zurück. Wie könnte man von der Schaltfläche aus auf das Hauptdokument zugreifen? |
2. |
Ändern Sie das Beispiel mit dem animierten Logo so, dass a) das Logo von rechts einschwebt, b) es diagonal von links oben kommt. |
3. |
Ändern Sie das permanente Werbebanner so um, dass es auf Mausklick verschwindet. |
|