JavaScript – M+T Pocket . Das Programmier-Handbuch (Office Einzeltitel) [Taschenbuch]

3.4
Dynamic HTML

In einen unmittelbaren Zusammenhang mit
JavaScript und Style-Sheets ist dynamisches HTML zu setzen. Der Begriff Dynamic
HTML oder kurz DHTML ist gemeinhin eine Erweiterung von HTML, die die statische
Darstellung von Webseiten mit Formatierungstechniken wie Style-Sheets und
Script-Technologien (meist JavaScript) verbindet. Aber das kommt darauf an, wer
von DHTML redet. Der Begriff ist weder eindeutig noch standardisiert oder sonst
irgendwie geschützt. Es ist keine offizielle Terminologie im WWW. Das W3C hat
den Begriff noch nicht abgesegnet und keinerlei verbindlichen Standard
erlassen. Zwar behaupten einige Firmen, sie hätten das Monopol für diesen
Begriff und nur das, was sie darunter verstehen, sei Dynamic HTML oder wie sie
es genau nennen. Es gibt einige Abarten von dem Begriff, die aber das Gleiche
beschreiben sollen. So gibt es eine Variante »Dynamic HTML« (mit großem D) und
eine weitere mit kleinem d (»dynamic HTML«). Obwohl die üblichen Protagonisten
im Internet unter dynamischem HTML alle eine andere Technik verstehen, ist
allen diesen Techniken gemeinsam, dass sie Veränderungen einer Webseite
erlauben, nachdem die Seite bereits in den Browser geladen worden ist – ohne,
dass die Seite neu vom Server geladen werden muss oder ein Serverkontakt
besteht. Diese Definition fasst das Wesen von dynamischem HTML recht genau.

Die nachträgliche Veränderung einer Webseite unter DHTML
kann einmal direkt durch den Anwender erfolgen. Der Anwender kann
beispielsweise über die Tastatur oder noch besser die Maus ein Element
auswählen und dann verändern. Etwa ein Element innerhalb der Webseite
verschieben (siehe das nachfolgende Beispiel). Aber auch auf Grund von Eingaben
bei anderen Elementen kann eine Veränderungen einer Seite erfolgen. Ein Element
einer Webseite kann sich verändern, wenn in einem anderen Element eine
Modifikation – etwa die Eingabe eines Wertes – erfolgt. Der Anwender wählt also
das dynamisch zu verändernde Element nicht direkt aus, sondern es ist eine
automatische Folgereaktion auf ein anderes Ereignis. Beide Möglichkeiten setzen
eine Programmierung von Vorgängen voraus und die wird auf Webseiten in der
Regel mit JavaScript durchgeführt.

Bei dynamischem HTML muss man allerdings sehr, sehr
vorsichtig zu Werke gehen, denn die verschiedenen Browser im Web reagieren auf
nicht genehme Anweisungen mit recht brutalen Abstürzen. So führt der Einsatz
der von Netscape erfundenen Layer-Technik im Internet Explorer zu massivsten Problemen. Aber auch der Netscape Navigator ab der Version 6 kann mit der ureigenen
Netscape-Technik nicht mehr umgehen[3].
Umgekehrt wird der Netscape Navigator vor der Version 6 mit der von Microsoft
unterstützten Variante von dynamischen HTML über den Jordan gehen. Eine
Trennung der beiden Browserwelten ist unumgänglich, aber wenn man dabei nicht
bis ins Detail aufpasst, kann das auch schiefgehen.
Zu Details bezüglich der Kompatibilitäten von Browsern und dynamischen HTML
siehe im Anhang Seite
377.

Ein – recht anspruchsvolles – Beispiel
zu dynamischem HTML soll zur Verdeutlichung durchgespielt werden. Dabei sei
ausdrücklich betont, dass das Beispiel einige nicht-triviale Techniken
einsetzt, deren ausführliche Besprechung den Rahmen dieses Buchs sprengen
würde. Das Beispiel macht aber die Leistungsfähigkeit von JavaScript in
Verbindung mit Style-Sheets, aber auch die Probleme (bezüglich des Internet
Explorers und des Netscape Navigators in den Versionen vor 4.7 muss auf jeden
Fall getrennt werden) deutlich.

<html>

<head>

<!– Zwei Stilvereinbarungen für Objekte, die per
JavaScript angesprochen werden sollen –>

<style>

#objekt1 { position:absolute; left:0;
top:0;

height:150; width:150;
clip:rect(0,150,150,0);

background-color:red;
layer-background-color:red;

}

#objekt2{ position:absolute; left:0;
top:0;

height:200; width:200;
clip:rect(0,200,200,0);

background-color:yellow;

layer-background-color:yellow;

}

</style>

<script language="JavaScript1.2">

/* Browsercheck <div> für den Internet Explorer
und alle Browser, die mit dem all-Objekt klar kommen, <layer> für
Netscape Navigator vor 6.0 */

var n = (document.layers) ? 1:0;

var ie = (document.all) ? 1:0;

var layer=(n)?’layer’:’div’;

function objektZiehen(obj,nest){

nest=(!nest) ?
”:’document.’+nest+’.’;

this.css=(n) ?
eval(nest+’document.’+obj):

eval(‘document.all.’+obj+’.style’);

this.evnt=(n)?
eval(nest+’document.’+obj):eval(obj);

this.getLeft=posLinks;

this.getTop=posTop;

this.moveIt=bewegen;

this.name=obj;

return this;

}

function bewegen(x,y){

this.css.left=x;

this.css.top=y;

}

function posLinks(){

x=(n)?
this.css.left:this.css.pixelLeft;

return x;

}

function posTop(){

y=(n)? this.css.top:this.css.pixelTop;

return y;

}

function dragInit(){

if(n)
document.captureEvents(Event.MOUSEMOVE | Event.MOUSEDOWN | Event.MOUSEUP);

document.onmousedown=mausTasteRunter;

document.onmouseup=mausTasteHoch;

document.onmousemove=mausBewegen;

}

function mausZeigerDrueber(num){

if(geladen)
zuZiehendeObjekte[num].isOver=true;

}

function mausZeigerRaus(num){

if(geladen) zuZiehendeObjekte[num].isOver=false;

}

function mausTasteHoch(){

for(var i=0; i<zuZiehendeObjekte.length;i++){

if(zuZiehendeObjekte[i].isOver) {

zuZiehendeObjekte[i].drag=false;

}

}

}

function mausTasteRunter(num){

x=(n)?num.pageX:event.x

y=(n)?num.pageY:event.y

for(var i=0;
i<zuZiehendeObjekte.length;i++){

if(zuZiehendeObjekte[i].isOver)
{

zuZiehendeObjekte[i].drag=true;

zuZiehendeObjekte[i].clickedX=

x-zuZiehendeObjekte[i].getLeft();

zuZiehendeObjekte[i].clickedY=

y-zuZiehendeObjekte[i].getTop();

cZIndex++;

zuZiehendeObjekte[i].css.zIndex=cZIndex;

}

}

}

function mausBewegen(e){

x=(n)?e.pageX:event.x;

y=(n)?e.pageY:event.y;

for(var i=0;
i<zuZiehendeObjekte.length;i++){

if(zuZiehendeObjekte[i].drag)

zuZiehendeObjekte[i].moveIt(

x-zuZiehendeObjekte[i].clickedX,

y-zuZiehendeObjekte[i].clickedY);

}

}

var geladen;

function init(){

dragInit();

zuZiehendeObjekte=new Array();

zuZiehendeObjekte[0]=new objektZiehen(‘objekt1’);

zuZiehendeObjekte[1]=new objektZiehen(‘objekt2’);

geladen=true;

}

cZIndex=10;

if(n || ie) onload=init;

</script>

</HEAD>

<BODY>

<h1 align=center>Herzlich Willkommen auf meiner
Webseite</h1>

<h2>Hier finden Sie kleine Experimente mit
Dynamischem HTML</h2>

<h2>Bewegen Sie die Maus auf die farbigen
Rechtecke und Ziehen Sie sie einfach mit der Maus über die Webseite</h2>

<!– Dynamisches Schreiben der Objekte für das
Verschieben –>

<script language="JavaScript1.2">document.write(‘<‘+layer+’
id="objekt1" onmouseover="mausZeigerDrueber(0)"
onmouseout="mausZeigerRaus(0)">Zieh mich
weg!</’+layer+’>’)</script>

<script
language="JavaScript1.2">document.writeln(‘<‘+layer+’
id="objekt2" onmouseover="mausZeigerDrueber(1)" onmouseout="mausZeigerRaus(1)">’);

// Text auf Rechteck unterscheidet sich je nach
Browser

if(ie){

document.writeln(‘Zieh Leine, Du MS-Zögling!’);

}

else {

document.writeln(‘Zieh mir Einen, Du NC-Zugvogel!’);

}

document.writeln(‘</’+layer+’>’);

</script>

</body>

</html>

Listing 3.8: Die Verbindung von JavaScript und
Style-Sheets im Rahmen von dynamischen HTML

Wenn Sie die Datei in einen Browser laden, werden – sofern
keine Konflikte wegen einer falschen Identifizierung auftreten – drei
HTML-Überschriften angezeigt, die teilweise von einem farbigen Rechteck
verdeckt werden.

Dieses Rechteck können Sie per Drag&Drop mit der Maus an
eine beliebige Stelle in der Webseite verschieben. Unter dem ersten Rechteck
kommt ein zweites Rechteck in anderer Farbe hervor, das genauso verschoben
werden kann.

Beachten Sie, dass das eine Rechteck je nach Browser
unterschiedlich beschriftet ist.

Bei dem Beispiel wird zur Trennung verschiedener Browser
bewusst ein im Web auf sehr vielen Seiten zu findendes Verfahren angewandt,
dass den Netscape Navigator 6 in die Falle tappen lässt und einen wichtigen
Baustein für die mangelnde Akzeptanz dieses Browsers darstellt. Die Trennung
der Browserwelten in dem Beispiel beruht darauf, zu überprüfen, ob der die
Seite ladende Browser die DHTML-Variante von Microsoft versteht (diese beruht
auf einem Objekt mit Namen all)
oder diejenige, welche das layers-Objekt
verwendet. Im ersten Fall wird der Browser als Internet Explorer bestimmt, im
zweiten Fall als Netscape Navigator. Der Netscape Navigator wird von dem
Verfahren korrekt als Netscape-Browser erkannt, aber da der Navigator 6 das layers-Objekt
nicht mehr unterstützt, wird er das folgende Prozedere nicht korrekt
durchgeführt (auf Seite 280 finden Sie mehr zur
Trennung von Browsern
).

Diese sehr populäre Form der Trennung von Browserwelten
berücksichtigt auch andere Browser nicht. So wird etwa der immer populärer
werdende Opera-Browser unter Umständen falsch zugeordnet. Dessen Anwender sind
aber in der glücklichen Lage, die Identifikation ihres Browsers sowohl auf
Internet Explorer, Netscape Navigator, Mozilla oder Opera einstellen zu können.

Es gibt noch andere Techniken, per JavaScript Browser zu
trennen. Diese sind zwar nicht so elegant, aber durch die tückische
Umstellung der Netscape-Philosophie zuverlässiger.

Die Verwendung des DMTML-Konzepts basiert zu einem Großteil
auf dem Document Object Model (DOM), das im Rahmen des Buchs noch intensiver behandelt wird (siehe Seite 225). Man sollte sich aber schon jetzt klarmachen,
dass eine Webseite nicht ein ununterscheidbares Ganzes ist, sondern aus vielen
kleinen Elementen (bzw. Objekten) zusammengesetzt ist. Einer gewissen Anzahl
von Überschriften, Absätzen, Grafiken, Formularen, etc. Unter dem DOM-Konzept
wird jedes Element einer Webseite vom Browser bei deren Laden registriert,
identifiziert, seine Position ermittelt und diese Informationen dann in einem
dynamischen Datenstapel (Stack) für die Seite gespeichert. Der Browser erstellt
mittels eines so genannten Parser eine Art dynamischer Datenbank für jede
Webseite, in der jeder HTML-Tag der Seite samt seinen Eigenschaften als eigener
Datensatz abgelegt ist. Elemente mit gemeinsamen Eigenschaften lassen sich
danach ordnen. Auf diese Weise kann der Browser jedes Element einer Seite
eindeutig wiederfinden und damit kann diese nachträglich verändert werden. Aber
wie in dem Beispiel deutlich gemacht wurde, gibt es unterschiedliche
Interpretationen dessen, wie DOM zu funktionieren hat.