Anzeige
Tutorialbeschreibung

Javascript und Ajax - Fenster

Javascript und Ajax - Fenster

In diesem Kapitel geht es um die Fenster. Javascript ist ja bekannt dafür, Browserfenster zu öffnen, zu bestimmen etc.


Das nun folgende Tutorial ist ein Auszug aus der 7. Auflage des Buches: JavaScript und Ajax von Christian Wenz.

Kapitel 8 Fenster

Das window-Objekt ist das wohl am häufigsten verwendete JavaScript-Objekt – und das, welches am seltensten ausgeschrieben wird. Die Methoden des Fenster-Objekts können nämlich aufgerufen werden, ohne dass man das Objekt voranstellt. Sie kennen ja bereits den Befehl window.alert("I have a dream"); alternativ dazu reicht auch alert("I have a dream"). Die Methode document.write() ist streng genommen auch eine Abkürzung. Das document-Objekt ist ein Unterobjekt des window-Objekts, ganz korrekt wäre also window.document.write(). Das window-Objekt bezeichnet ein Browserfenster oder einen Frame, denn jeder Frame wird intern als eigenes Fenster behandelt. Auf den aktuellen Frame beziehungsweise das aktuelle Browserfenster greift man mit window oder self oder this zu. Wie gesagt – den Sermon könnte man sich sparen, aber man macht seine Skripten auf diese Weise übersichtlicher und programmiert auch sauberer. Als Entwickler muss man immer fürchten, dass es eine neue Browserversion oder einen ganz neuen Browser gibt, der die Syntax etwas strenger auslegt (auch wenn das unwahrscheinlich ist).


8.1 Modale Fenster  

Unter einem modalen Fenster einer Applikation versteht man ein Fenster, das in den Vordergrund tritt, den Fokus bekommt und den Zugriff auf das Hauptapplikationsfenster sperrt: Solange das (modale) Fenster offen ist, kann auf das Hauptfenster nicht mehr zugegriffen werden. Ein Beispiel ist die Meldung einer Textverarbeitung, die den Benutzer vor dem Verlassen des Programms fragt, ob das aktuelle Dokument gespeichert werden soll (sofern es noch nicht gespeichert wurde). Sie müssen entweder auf Ja, Nein oder Abbrechen klicken, um wieder auf die Textverarbeitung zugreifen zu können. Auch die Cookie-Warnung der diversen Browser ist ein modales Fenster.

Bilder

Abbildung 8.1     Eine Cookiewarnung

Sie merken es bereits: Ein modales Fenster greift stark in die Benutzerführung ein. Sie können mit JavaScript auch modale Fenster erstellen, aber gehen Sie mit dieser Möglichkeit sehr sparsam um. Zum einen geben Sie damit einem anderen Fenster den Fokus, was störend ist, und zum anderen gibt das Betriebssystem bei modalen Fenstern manchmal einen Warnton aus, wie man ihn nur aus schlechten Fernsehserien kennt.


8.1.1 Warnung – nur im Notfall  

Eine Möglichkeit, ein modales Fenster mit JavaScript zu erstellen, haben Sie bereits kennen gelernt: window.alert() oder kurz alert(). Damit wird ein modales Fenster mit einem Text angezeigt; als Icon wird ein Warndreieck verwendet (deswegen auch der Name: »alert«, dt. »Warnung«).

Da die Syntax des Befehls sehr einfach ist – Sie schreiben alert("I have a dream"), und »I have a dream« wird angezeigt –, kommen wir gleich zu den Anwendungsmöglichkeiten. Es wird nur ein Text angezeigt, was ja auch mit anderen Mitteln möglich wäre. Die Besonderheit dieser Funktion ist gleichzeitig auch ihr großer Nachteil: Das modale Fenster muss erst einmal geschlossen werden, um weitermachen zu können. Wenn Sie also eine besonders wichtige Mitteilung zu machen haben, können Sie so ein Warnfenster verwenden.

Während der Programmierung wird die Funktion allerdings auch eingesetzt. Bei der Fehlersuche leistet window.alert() wertvolle Dienste, da der Wert einzelner Variablen schnell angezeigt werden kann. Ein document.write() ist ja nicht möglich, sobald ein Dokument vollständig geladen worden ist.

Im folgenden Beispiel befindet sich ein Stück Programmcode, der nicht funktioniert:

<html>
<head>
<title>Fehlersuche window.alert()</title>
</head>
<body>
<h1>Alle ungeraden Zahlen kleiner als 10</h1>
<script type="text/javascript"><!--
var rest;
for (var i=1; i<10; i++) {
   rest = i % 2;
   if (rest = 1) {
      document.write(i + " ist ungerade!" + "<"+"br"+" />");
   }
}
//--></script>
</body>
</html>

Dieses Listing liefert als Ergebnis ein paar Zahlen zu viel (siehe Abbildung 8.2).

Bilder

Abbildung 8.2     Ein offensichtlich falsches Ergebnis

Mit window.alert() kommt man dem Fehler auf die Schliche, wenn man sich die Variable rest an den richtigen Stellen anzeigen lässt:

<html>
<head>
<title>Fehlersuche window.alert()</title>
</head>
<body>
<h1>Alle ungeraden Zahlen kleiner als 10</h1>
<script type="text/javascript"><!--
var rest;
for (var i=1; i<10; i++) {
   rest = i % 2;
   alert("vorher: "+rest);
   if (rest=1) {
      alert("nachher: "+rest);
      document.write(i + " ist ungerade!" + "<"+"br"+" />");
   }
}
//--></script>
</body>
</html>

Des Rätsels Lösung liegt in der folgenden Abfrage:

if (rest = 1)

Hierdurch wird die Variable rest mit dem Wert 1 belegt, und diese Anweisung liefert – bei einer if-Anweisung – den Wert true. Korrekt wäre ein Vergleich:

if (rest == 1)


8.1.2 Bestätigungen  

Bot das letzte modale Fenster noch sehr wenig Eingriffsmöglichkeiten – nur eine OK-Schaltfläche –, so kann man mit window.confirm() ein modales Fenster mit zwei Schaltflächen anbieten: je nach Betriebssystem und Sprache OK und Cancel oder OK und Abbrechen. Klickt der Benutzer auf OK, so liefert die Methode true zurück, ansonsten false.

Auch hier macht Netscape wieder vor, wie man diese Methode sinnvoll einsetzen könnte. Als das Mozilla-Projekt noch ganz am Anfang stand, konnte man den aktuellen Entwicklungsstand des Browsers herunterladen. Zwar gab es schon damals in unterschiedlichen Abständen so genannte Milestones (Meilensteine), die auch schon relativ stabil liefen, aber jede Nacht wird der aktuelle Stand der Dinge direkt auf dem Entwicklungsserver automatisch kompiliert und via FTP zur Verfügung gestellt. Es ist nicht sichergestellt, dass diese Version überhaupt startet! Aus diesem Grund wurde früher mit JavaScript sicherheitshalber noch einmal nachgefragt, ob der Benutzer diese Version wirklich herunterladen will. Der zugehörige Code sieht dort ungefähr folgendermaßen aus:

<html>
<head>
<title>window.confirm()</title>
</head>
<body>
<h1>Laden Sie die Alpha-Version des neuen Browsers herunter!</h1>
<a href="datei.zip" onclick="return confirm('Are you sure you want to do this crazy thing?');">Hier klicken</a>
</body>
</html>

Hier sind ein paar zusätzliche Erklärungen erforderlich. Der Befehl confirm('Are you sure you want to do this crazy thing?') öffnet ein modales Fenster. Klickt der Benutzer darin auf OK, wird true zurückgeliefert, ansonsten false. Stimmt der Benutzer also dem Download zu, so lautet das onclick-Attribut des <a>-Tags return true, ansonsten return false.

Auch bei confirm() handelt es sich um eine Kurzform – für window. confirm()!

Bilder

Abbildung 8.3     Download für Furchtlose

Die Bedeutung ist relativ einfach: Im obigen Fall kollidieren der HTML-Link und der onclick-Event-Handler. Ein Klicken auf den Link führt dazu, dass die Datei datei.zip vom Webserver angefordert wird; der onclick-Event-Handler führt den entsprechenden JavaScript-Code aus. Wer macht das Rennen?

Der Trick hierbei ist folgender: Der JavaScript-Code wird auf jeden Fall ausgeführt. Endet der Code mit return true, so wird daraufhin das Ziel des HTML-Links aufgerufen; bei return false wird der HTML-Link nicht aufgerufen. So funktioniert auch die Abfrage von oben: Verneint der Benutzer die Frage im modalen Fenster, so lautet der onclick-Event-Handler return false und der Link wird nicht ausgeführt. Bejaht der Benutzer die Abfrage, so lautet der onclick-Event-Handler return true und datei.zip wird wie geplant aufgerufen.


8.1.3 Benutzereingaben 
topBilder

Es gibt noch eine weitere Stufe, und diese ist das luxuriöseste Fenster, das Sie mit einem einzelnen JavaScript-Befehl erzeugen können: window. prompt(). Außer den Schaltflächen OK und Cancel (oder Abbrechen) gibt es noch ein einzeiliges Texteingabefeld. Bei der Überprüfung auf Vollständigkeit von Formulareingaben kann das recht nützlich werden.

Der Rückgabewert der Methode ist der eingegebene Text, sofern der Benutzer auf OK klickt. Beim Anklicken der Schaltfläche Cancel oder Abbrechen wird der spezielle Wert null zurückgegeben, egal was in das Textfeld eingegeben worden ist. Der folgende Code fragt den Namen des Benutzers ab und gibt ihn in einem weiteren modalen Fenster aus – sofern die Schaltfläche OK angeklickt und ein Name eingegeben worden ist.

<html>
<head>
<title>window.prompt()</title>
</head>
<body>
<h1>What's your name?</h1>
<script type="text/javascript"><!--
var benutzername = prompt("Wie heißen Sie?", "<Ihr Name>");
if (benutzername) {
   alert("Guten Tag, Herr/Frau " + benutzername);
}
//--></script>
</body>
</html>

Zwei Dinge sind bemerkenswert:

gpBilder
 
Anstelle von window.prompt() können Sie wie gehabt auch prompt() verwenden.
gpBilder
 
Der erste Parameter von window.prompt() ist der Text, der im Fenster angezeigt wird; der zweite (optionale!) Parameter ist der Text, mit dem das Textfeld vorbelegt ist.

Bilder

Abbildung 8.4     Dateneingabe mit JavaScript

Wie ein Test im Browser zeigt, wird der auf if (benutzername) folgende Befehl auch dann nicht ausgeführt, wenn die Schaltfläche OK angeklickt, aber kein Name eingegeben worden ist.

 

8.2 Navigationsleiste mit JavaScript 
topBilder

Die Navigationsleiste des Browsers wird ziemlich häufig benutzt. Vor allem die Schaltflächen Zurück (oder Back), Drucken (oder Print) und Neu laden (oder Aktualisieren, Refresh, Reload) werden angeblich am häufigsten angeklickt. Mit JavaScript kann man diese Funktionalität nachbilden.


8.2.1 Das History-Objekt  

Die History eines Browserfensters oder eines Frames ist nichts weiter als eine Liste der zuvor besuchten Seiten des aktuellen Fensters oder Frames. Beim Internet Explorer gibt es einen eigenen Ordner namens History oder Verlauf, der die globale History, also alle aufgerufenen Seiten enthält, während der Netscape Navigator diese Daten in einer einzelnen Datei ablegt. In Mozilla-Browsern heißt diese Funktionalität zumeist Chronik. Auf die Elemente des History-Objekts haben Sie natürlich keinen Schreibzugriff. Stellen Sie sich vor, eine bösartige Seite würde die gesamte History des Benutzers überschreiben. Egal, ob der Benutzer vor oder zurück will, er würde immer auf der falschen Seite landen. Aber auch der Lesezugriff ist stark eingeschränkt, und zwar aus Sicherheitsgründen. Wenn man mit JavaScript (oder anderen Mitteln) die History-Liste des Benutzers auslesen könnte, wäre der gläserne Benutzer geschaffen. Manchmal werden auch Passwörter und andere vertrauliche Informationen in der URL übertragen; ein Lesezugriff wäre also ein Unding. Mit einem signierten Skript kann man auf diese Werte zugreifen, aber das ist nicht das Thema dieses Kapitels.

Schon interessanter ist es, in der History nach vorn oder hinten zu springen, wie man es auch mit den Schaltflächen in der Navigationsleiste des Browsers machen kann.

Wenn Sie einen englischsprachigen Browser verwenden, haben Sie die Funktionsnamen direkt vor sich: back() springt zurück, forward() nach vorn. Mit dem folgenden Skript wird ein Teil der Navigationsleiste nachgebildet. Beachten Sie, dass Sie zwar auch mit window.history. methode() auf die Methoden des History-Objekts zugreifen können; aber wie bereits schon mehrfach gesagt wurde, kann man das window. auch weglassen.

<html>
<head>
<title>History-Objekt</title>
</head>
<body>
<h1>Navigation mit JavaScript</h1>
<a href="javascript:history.back();">Zurück</a> -
<a href="javascript:history.forward();">Vor</a>
</body>
</html>

Es gibt noch eine weitere Methode des history-Objekts: history.go(). Mit dieser Methode kann man in der History mehr als einen Eintrag vor- oder zurückspringen. Als Parameter wird hierbei angegeben, um wie viel vor (positiver Wert) oder zurück (negativer Wert) gesprungen wird. Statt history.back() kann man also auch history.go(-1) verwenden; history.forward() wird durch history.go(1) ersetzt. Mit history.go(0) wird übrigens die aktuelle Seite neu geladen.


8.2.2 Vorwärts und rückwärts, Teil 2  

Jeder Frame (und jeder Iframe) hat seine eigene History. Man kann also problemlos zwischen den Seiten hin- und herspringen, die in einem bestimmten Frame geladen worden sind. Nun kommt es in der Realität aber des Öfteren vor, dass sich der Inhalt mehrerer Frames ändert. Stellen Sie sich vor, Sie haben eine Webseite mit einem Frame für den Inhalt und einem Frame für Werbebanner. Der Werbebanner-Frame wird alle 60 Sekunden neu geladen, während im Inhalts-Frame immer dann neuer Inhalt geladen wird, wenn der Benutzer auf einen Link klickt. Mit den bisherigen Methoden ist es zwar möglich, die History jedes einzelnen Frames zu verfolgen, nicht aber die globale History des Fensters, die aus einer Mischung von Seiten im Inhalts- und im Werbe-Frame besteht.

Bei Netscape- und Mozilla-Browsern hat das window-Objekt ebenfalls die Methoden back() und forward(), die es dem Benutzer erlauben, durch die globale History des Fensters zu navigieren. Der Internet Explorer kennt diese Methoden dagegen nicht. Mit dem folgenden Skript, das am besten in einem Frame platziert wird, kann der Benutzer durch die History des Hauptfensters navigieren:

<html>
<head>
<title>window-Objekt: vorwärts und rückwärts</title>
</head>
<body>
<h1>Navigation mit JavaScript</h1>
<a href="javascript:top.Hauptfenster.back();">Zurück</a> -
<a href="javascript:top.Hauptfenster.forward();">Vor</a>
</body>
</html>

Ihnen fehlt bisher noch das Wissen, wie Sie auf Frames zugreifen können; auch die Syntax top.Hauptfenster.back() kennen Sie noch nicht. Keine Bange: In Kapitel 10 erfahren Sie mehr.


8.2.3 Drucken mit JavaScript 
topBilder

Eine sehr häufige Frage in Newsgroups lautet: Wie kann ich mit JavaScript drucken? Die Antwort ist nur auf den allerersten Blick unbefriedigend: Es ist nicht möglich, automatisch Daten zum Drucker zu senden – stellen Sie sich nur einmal vor, Sie surfen, und plötzlich fängt Ihr Drucker an, unkontrolliert Seiten auszuspucken.

Aber zurück zum Thema: Das Dialogfenster des Drucken-Dialogs kann nicht nur mit dem entsprechenden Menübefehl oder der Schaltfläche in der Navigationsleiste aufgerufen werden. JavaScript unterstützt die Methode print() des window-Objekts, die genau dieses Dialogfenster aufruft. Zwar haben Sie auf den ersten Blick keinen Vorteil gegenüber der Arbeit mit der Navigationsleiste, aber viele Benutzer rufen gern das Kontextmenü des Fensters oder Frames auf und wählen dort den Drucken-Eintrag. Der Netscape Navigator erlaubt so etwas nicht, und seine Benutzer freuen sich sicherlich über den zusätzlichen Komfort, wenn Sie das Drucken mit JavaScript ermöglichen. Weiter unten in diesem Kapitel werden Sie außerdem Fenster ohne Navigationsleiste und ohne Menüleiste kennen lernen. Wer hier nicht die Tastenkombination zum Drucken kennt, hat ein ernsthaftes Problem, den Inhalt des Fensters zu Papier zu bringen. Eine JavaScript-Lösung schafft hier eine Erleichterung.

Im folgenden Beispiel finden Sie zusätzlich eine Überprüfung, ob der Browser die print()-Methode überhaupt unterstützt. Das ist zwar heutzutage nicht mehr notwendig, aber zeigt auf, wie Sie generell bestimmte JavaScript-Fähigkeiten eines Browsers prüfen können.

<html>
<head>
<title>window.print()</title>
<script type="text/javascript"><!--
function drucken(){
   if (window.print) {
      window.print();
   } else {
      window.alert("Leider nicht möglich!");
   }
}
</head>
<body>
<h1>Drucken mit JavaScript</h1>
<a href="javascript:drucken()">Drucken</a><br>
</body>
</html>

Beachten Sie, dass die Abfrage if (window.print) heißen muss. Damit wird überprüft, ob die Methode window.print() vorhanden ist. Die Abfrage if (window.print()) funktioniert nicht, die Funktion würde – sofern vorhanden – auf jeden Fall ausgeführt werden.

 

8.3 Die Statuszeile 
topBilder

Kommen wir nun zu einer der umstrittensten JavaScript-Anwendungen. Die meisten Browserfenster haben eine Statuszeile, in der während des Ladens eines Dokuments der Ladestatus angezeigt und beim Bewegen der Maus über einen Link das Ziel des Links angezeigt wird. Schon bald nach dem Erscheinen des Netscape Navigator 2 sind pfiffige Programmierer auf die Idee gekommen, die Statuszeile als bequeme Möglichkeit der Textausgabe zu verwenden. Natürlich ist das bequem, und es gibt auch nützliche Anwendungen. Diese sind leider derzeit in der Minderheit, und in den folgenden Abschnitten soll eine deutliche Warnung ausgesprochen werden, was Sie tunlichst vermeiden sollten. Dem Benutzer dient die Statuszeile als Informationsquelle, und sie sollte nicht für Spielereien missbraucht werden.


8.3.1 Erläuternde Links  

Unerfahrenen Anwendern sollte man die Navigation im World Wide Web so einfach und intuitiv wie möglich gestalten. Irgendwann ist es in Mode gekommen, erklärende Hilfetexte in der Statuszeile des Browsers zu platzieren. Das bietet sich vor allem bei Hyperlinks an. Es ist doch viel schicker, wenn in der Statuszeile Hier geht's zu unseren Produkten anstelle von http://www.ihrefirma.xy/produkte/index.html steht.

Die Umsetzung ist nicht weiter schwierig. Die entsprechende Eigenschaft, die den Text in der Statuszeile angibt, ist window.status; lediglich einen kleinen Fallstrick müssen Sie noch umgehen. Der folgende Code liefert nicht mit allen Browsern das gewünschte Ergebnis:

<a href="/produkte/index.html" _fcksavedurl="/produkte/index.html" _fcksavedurl="/produkte/index.html" _fcksavedurl="/produkte/index.html" _fcksavedurl="/produkte/index.html" _fcksavedurl="/produkte/index.html" onmouseover="window.status='Unsere Produkte';">Produkte</a>

Der Text wird kurzzeitig in der Statuszeile angezeigt, aber dann erscheint die Ziel-URL des Hyperlinks. Der Grund: Auch hier kollidieren der Event-Handler und die Browser-Aktion, wenn der Mauszeiger über den Hyperlink fährt. Sie wissen eigentlich bereits von oben, wie Sie dem JavaScript-Event-Handler den Vorrang geben – doch leider funktioniert das an dieser Stelle nicht. Es handelt sich hier um eine Art unlogischer Ausnahme. Nur wenn der Event-Handler auf return true endet, wird der Text dauerhaft in der Statuszeile angezeigt, andernfalls nicht.

Noch ein kleiner Hinweis, bevor der HTML-Code präsentiert wird: Vergessen Sie nicht, mit dem onmouseout-Event-Handler die Eigenschaft window.status wieder auf eine leere Zeichenkette zu setzen; ansonsten bleibt der Text in der Stauszeile stehen.

<a href="/produkte/index.html" _fcksavedurl="/produkte/index.html" _fcksavedurl="/produkte/index.html" _fcksavedurl="/produkte/index.html" _fcksavedurl="/produkte/index.html" _fcksavedurl="/produkte/index.html" onmouseover="window.
status='Unsere Produkte'; return true;"
onmouseout="window.status=''; return true;">Produkte</a>

Viele erfahrene Benutzer wissen eigentlich ganz gern, wohin ein Link führt. Ich öffne beispielsweise Links gern in einem neuen Fenster. Wird jedoch die Statuszeile überschrieben, so kann man nicht feststellen, ob der Link eine HTML-Seite aufruft oder eine JavaScript-Funktion (im zweiten Fall ist das Öffnen im neuen Fenster nicht möglich). Wenn Sie auf diese Form von erklärenden Links nicht verzichten wollen, sollten Sie wenigstens zusätzlich die URL der Zielseite in der Statuszeile angeben.

Einige Browser bieten es ihren Benutzern mittlerweile an, den JavaScript-Zugriff auf die Statuszeile zu unterbinden. Sie können sich also nicht mehr darauf verlassen, dass Ihre Besucher irgendetwas in der Statuszeile sehen. Einige Versionen des Internet Explorers zeigen die Statuszeile standardmäßig überhaupt nicht an.


8.3.2 Laufschrift 
topBilder

Sie kennen das sicherlich: In der Statuszeile des Browsers läuft ein Text von rechts nach links. Um es gleich vorweg zu sagen: Dieser Effekt gilt seit ungefähr acht Jahren als veraltet, sorgt nur für Verärgerung beim Benutzer und besitzt keinen wirklichen Nutzen. Warum der Effekt hier trotzdem vorgeführt wird? Es handelt sich hierbei um eines der Standardbeispiele für die Möglichkeiten von JavaScript, und man muss ihn einfach einmal gesehen haben.

Timeouts setzen

Oft ist es bei der JavaScript-Programmierung notwendig, einen Befehl nicht sofort auszuführen, sondern erst später. Dafür benutzt man so genannte Timeouts, die mit einer Methode des window-Objekts gesetzt werden können. Die Befehlssyntax lautet leicht vereinfacht folgendermaßen:

window.setTimeout(Befehl, Verzögerung)

Dabei ist Befehl eine Zeichenkette, die den entsprechenden JavaScript-Befehl enthält, und Verzögerung ist die Zeitspanne in Millisekunden, die verstreichen muss, bis der Befehl ausgeführt wird. Folgender Befehl ruft nach fünf Sekunden die Homepage des Galileo-Verlags auf:

setTimeout("location.href='http://www.galileo-press.de/';",
5000)

Beachten Sie, dass folgender Code nicht funktionieren wird:

<html>
<head>
<title>Timeouts</title>
<script type="text/javascript"><!--
function galileo() {
   var galileo_url = "http://www.galileo-press.de/";
   setTimeout("location.href=galileo_url", 5000);
}
//--></script>
</head>
<body onload="galileo();">
<h1>Verbinde mit Galileo Press...</h1>
</body>
</html>

Der Grund ist, dass galileo_url eine lokale Variable ist. Wenn der Befehl nach fünf Sekunden ausgeführt wird, steht diese Variable nicht mehr zur Verfügung, da sie außerhalb der Funktion ausgeführt wird. Es gibt drei Auswege aus diesem Dilemma:

1. Verwenden Sie eine globale Variable.
       
2. Verwenden Sie eine eigene Funktion.
       
3. Verwenden Sie keine Variable.
       

Zu 1.: Der <script>-Teil des vorherigen Listings muss folgendermaßen geändert werden:

<script type="text/javascript"><!--
var galileo_url;
function galileo() { galileo_url = "http://www.galileo-press.de/"; setTimeout("location.href=galileo_url", 5000); } //--></script>

Zu 2.: Der <script>-Teil muss folgendermaßen geändert werden:

<script type="text/javascript"><!--
function galileo_laden() {
   var galileo_url = "http://www.galileo-press.de/";
   location.href = galileo_url;
}
function galileo() {
   setTimeout("galileo_laden()", 5000);
}
//--></script>

Zu 3.: Der <script>-Teil muss folgendermaßen geändert werden:

<script type="text/javascript"><!--
function galileo() {
   var galileo_url = "http://www.galileo-press.de/";
   setTimeout("location.href='" + galileo_url + "'", 5000);
}
//--></script>

Timeouts löschen

Es kommt in der Praxis des Öfteren vor, dass man den Befehl dann doch nicht mehr ausführen, also den Timeout löschen will. Jeder Aufruf von setTimeout() gibt einen Wert zurück, der als eindeutiger Identifikator für den Timeout dient. Je nach Browser ist das entweder ein numerischer Wert oder ein Objekt. Hüten Sie sich also davor, numerische Berechnungen mit dem Rückgabewert auszuführen. Sie können aber jederzeit den Rückgabewert der Methode window.clearTimeout() als Parameter übergeben, um den Timeout zu löschen.

Im folgenden Beispiel wird wieder die Homepage von Galileo Press nach fünf Sekunden aufgerufen, außer der Benutzer klickt auf den Link auf der Seite. Beachten Sie, dass die von setTimeout() zurückgegebene ID in einer globalen Variablen gespeichert werden muss.

<html>
<head>
<title>Timeouts setzen und löschen</title>
<script type="text/javascript"><!--
var ID;
function galileo() {
   ID = setTimeout("location.href='http://www.galileo-press.de/'", 5000);
}
function kein_galileo() {
   clearTimeout(ID);
}
//--></script>
</head>
<body onload="galileo();">
<a href="javascript:kein_galileo();">Laden stoppen</a>
</body>
</html>

Laufschrift mit Timeouts

Kommen wir zum ursprünglichen Beispiel zurück: zur Laufschrift. Diese ist mit Timeouts recht schnell zu erstellen, und zwar folgendermaßen:

gpBilder
 
In einer globalen Variablen wird der Text abgespeichert, der in der Statuszeile angezeigt werden soll.
gpBilder
 
In einer JavaScript-Funktion wird der entsprechende Text in der Statuszeile angezeigt, und dann wird der Text verändert, so dass der Scroll-Effekt entsteht (der erste Buchstabe wird entfernt und hinten wieder angehängt).
gpBilder
 
Dann wird ein Timeout gesetzt, der die Funktion nach Ablauf einer gewissen Zeitspanne wieder aufruft.

Bilder

Abbildung 8.5     Die Laufschrift in der Statuszeile des Browsers

Nachteile

Noch ein paar Sätze zu Laufschriften: Ihnen wird aufgefallen sein, dass auf größeren und seriösen Seiten keine Statuszeilen-Laufschriften vorkommen (außer eine Zeit lang auf den Seiten einer Gruppe von Online-Versendern, aber Ausnahmen bestätigen bekanntermaßen die Regel). Das hat auch seinen Grund. Durch die Laufschrift ist die Statuszeile permanent belegt, und man kann beispielsweise das Ziel von Links nicht mehr sehen. Eine nützliche Anwendung für eine Laufschrift habe ich auch noch nirgends gesehen. Wichtige Mitteilungen kann man auch an exponierter Stelle auf der eigentlichen Webseite platzieren. Mit Laufschriften ist es beinahe so wie mit dem <marquee>-HTML-Tag (das beim Internet Explorer eine Laufschrift erzeugt): Man disqualifiziert sich eher, als dass man mit seinen JavaScript-Kenntnissen imponiert.

Man kann auch in einem Formular-Eingabefeld eine Laufschrift erzeugen. Das ist nicht ganz so schlimm, da wenigstens die Statuszeile frei bleibt. Hat man viel Text und wenig Platz, ist das akzeptabel, aber ansonsten gilt: Verzichten Sie auf solche Spielereien, wenn der Sinn des Ganzen im Verborgenen bleibt.

Außerdem unterbinden mittlerweile viele Browser, dass JavaScript Zugriff auf die Statuszeile erhält.

Bequemere Timeouts

Sie haben gesehen, dass die Implementierung der Laufschrift ein wenig umständlich war: Eine Funktion musste geschrieben werden, die sich selbst nach ein paar Sekunden wieder aufruft. Alternativ gibt es die Möglichkeit, eine Funktion von außen wiederholt aufzurufen, und zwar immer nach Ablauf einer festen Zeitspanne. Der erforderliche Befehl heißt setInterval(), und der korrespondierende Löschbefehl heißt clearInterval(). Der erste Parameter ist wieder der JavaScript-Befehl oder Funktionsname, der zweite Parameter ist die Verzögerung in Millisekunden zwischen den Aufrufen. Das Laufschrift-Beispiel jedenfalls kann folgendermaßen umgeschrieben werden:

<html>
<head>
<title>Laufschrift </title>
<script type="text/javascript"><!--
var lauftext = " +++ Read my lips: no tax on beer ";
function laufschrift() {
   window.status = lauftext;
   lauftext = lauftext.substring(1, lauftext.length)
      + lauftext.substring(0,1);
}
setInterval("laufschrift()", 5000);
//--></script> </head> <body> <h1>Laufschrift mit JavaScript</h1> </body> </html>

8.4 Das location-Objekt 
topBilder
topBilder

Als Nächstes sehen wir uns das Objekt location an. Sie haben es ja schon bei den verschiedensten Beispielen in diesem Buch kennen gelernt, und es scheint etwas mit der aktuellen URL des Browserfensters zu tun zu haben.

Eine URL besteht aus verschiedenen Teilen, die Sie in Abbildung 8.6 zusammen mit dem Namen der entsprechenden JavaScript-Eigenschaft sehen können.

AbbildungBilder

Abbildung 8.6     Die Eigenschaften des location-Objekts

In der Praxis wird location.href am häufigsten eingesetzt. Zwar liefert auch location die komplette URL der aktuellen Seite zurück, es tut das aber nur bei neueren Browsern konsistent. Um abwärtskompatibel zu bleiben, ist die Verwendung von location.href zwingend.

Interessanter sind da schon die Methoden des location-Objekts. location.reload() lädt die aktuelle URL neu. Ohne Parameter oder mit dem Parameter false wird die URL aus dem Cache des Browsers neu geladen, sofern sie verfügbar ist; wird true übergeben, so wird eine Anforderung an den Server geschickt. Das entspricht dem Klicken auf die Schaltfläche Reload der Navigationsleiste bei gleichzeitigem Drücken der (ª)-Taste. Beachten Sie jedoch, dass hierbei Formulareingaben gelöscht werden. Um ein so genanntes »weiches Neuladen« zu veranlassen (das die aktuelle Scroll-Position im Dokument und in Formulareingaben beibehält), müssen Sie das bereits bekannte history.go(0) verwenden.

JavaScript bietet auch die Methode location.replace(). Hiermit kann man die History-Liste zumindest in begrenztem Umfang manipulieren. Wenn Sie mit location.replace(url) eine neue URL laden, nimmt diese in der History-Liste die Position der vorherigen Seite ein. Angenommen, Sie haben zuerst die Seite A.html geladen, gehen dann auf B.html und laden dann mittels location.replace("C.html") die Seite C.html. Ein Klick auf die Zurück-Schaltfläche in der Navigationsleiste führt dann zur Seite A.html zurück. Dies wird oft bei mehrseitigen Formularen verwendet, wenn man vermeiden will, dass der Benutzer zurückspringt und alte Eingaben nochmals ändert.

Man kann nicht nur den Inhalt bestehender Fenster verändern, man kann auch gleich neue Fenster erstellen. Das kann sowohl zum Nutzen als auch sehr zum Ärger des Benutzers geschehen. In diesem Kapitel sehen Sie beides.

Früher war es fast unbezahlbar, eine .de-Domain zu registrieren, so dass man schon erwägen musste, eine vergleichsweise günstige .com-Domain zu erwerben. Heutzutage hat sich das umgekehrt: Mehrere Firmen buhlen um Kundschaft und unterbieten sich gegenseitig mit den Preisen. Für den geringen Preis gibt es jedoch oft auch nur geringe Leistungen. Manche Anbieter sind auf die Idee gekommen, als Gegenleistung für den Kampfpreis ein Werbebanner auf den Seiten einzublenden. Damit man das Banner auch besonders gut sieht, wird es in einem eigenen, neuen Fenster angezeigt. Bei Seiten mit besonders zwielichtigem Inhalt wird das auf die Spitze getrieben, und es werden sogar mehrere neue Fenster geöffnet, was ich natürlich nur vom Hörensagen weiß.

 

8.5 Ein neues Fenster öffnen 
topBilder

Die Methode zum Öffnen eines neuen Fensters heißt window.open(). Dieser Methode werden bis zu drei Parameter übergeben, mindestens jedoch einer.


8.5.1 Ein Fenster öffnen und füllen  

var fenster = window.open(URL, Fenstername, Optionen);

Der erste Parameter, URL, enthält die URL der Seite, die in das neue Fenster geladen werden soll. Ist URL eine leere Zeichenkette, so wird das Fenster zwar geöffnet, aber es wird keine Seite hineingeladen.

Die Position des neuen Fensters lässt sich per JavaScript bestimmen; ansonsten hängt sie vom Browser ab. Die Größe hängt auch vom Browser ab, kann jedoch auch eingestellt werden (siehe weiter unten).

Mit dem folgenden Code wird die Homepage von Galileo Press in ein neues Fenster geladen:

var fenster = window.open("http://www.galileo-press.de/");

Verwenden Sie stets window.open(), nicht bloß open().

Die Variable fenster ist eine Referenz auf das neue Fenster. Somit kann auf Eigenschaften des Fensters zugegriffen werden, beispielsweise auf das Objekt location oder auf das Objekt document. Letzteres ist besonders interessant, weil man so (mittels write()) den Inhalt des Fensters komplett mit JavaScript erzeugen kann. Die folgende Funktion öffnet ein neues Fenster und erzeugt in diesem eine HTML-Seite, die den übergebenen Parameter ausgibt.

function tag(s) {
   return "<" + s + ">";
}
function neuesfenster(text) {
   var fenster = window.open("");
   if (fenster!=null) {  // Hat das Öffnen 
                         // des Fensters geklappt?
      fenster.document.open();  // Öffnen für 
                                // Schreibzugriff, Pflicht!
      fenster.document.write(tag("html") + tag("body"));
      fenster.document.write(tag("h1") + text +
        tag ("/h1"));
      fenster.document.write(tag("/body") +
        tag ("/html"));
      fenster.document.close();  // Schreibzugriff
                                 // beenden, Pflicht!
   }
}

Wie Sie sehen, können Sie mit document.open(), write() und close() rein theoretisch in jedem Fenster jeden beliebigen HTML-Code erzeugen; das Anhängen geht nicht, aber ein Überschreiben ist möglich. Einige Leute haben das recht trickreich ausgenutzt und beispielsweise die Login-Masken mancher Webmail-Dienste mit dieser Methode überschrieben, wodurch sie die Passwörter von ahnungslosen Benutzern ausspionieren konnten. Aus diesem Grund erlauben die neueren Versionen aller Browser nur noch das Überschreiben von Fenstern, deren aktuelle URL von derselben Domain stammt wie das Fenster mit dem Skript. Es ist also beispielsweise unmöglich, ein unauffälliges Überwachungsfenster zu öffnen, das sich im Hintergrund hält und nur darauf wartet, dass in einem anderen Browserfenster ein Webmail-Anbieter besucht wird, um dann aktiv zu werden.

Popup-Blocker sind sehr populär, die meisten Webbrowser haben mittlerweile einen. Sie können sich also nicht darauf verlassen, dass sich das neue Fenster beim Besucher auch tatsächlich öffnet!


8.5.2 Ein Fenster öffnen und verlinken  

Der zweite Parameter von window.open() gibt den Namen des neuen Fensters an. Man kann diesen Namen – genauso wie bei Frames – als Wert des target-Attributs eines HTML-Links angeben, und das Ziel des Links wird in dem neuen Fenster geöffnet und nicht im aktuellen Fenster. Wenn Sie window.open() zweimal verwenden und dabei einen identischen zweiten Parameter angeben, wird nur ein Fenster geöffnet.

Die folgende Seite öffnet beim Laden ein neues Fenster mit der Homepage von Galileo Press. Die anderen Links auf der HTML-Seite öffnen die Homepages einiger Browserhersteller – in dem neuen Fenster.

<html>
<head>
<title>Neue Fenster</title>
<script type="text/javascript"><!--
function neuesfenster() {
  var fenster = window.open("http://www.galileo-press.de/", "neu");
}
//--></script>
</head>
<body onload="neuesfenster()">
<h1>Hier einige Links...</h1>

<ul>
   <li>
      <a href="http://www.microsoft.com/"
      target="neu">Microsoft</a>
   </li>
   <li>
      <a href="http://www.mozilla.com/"
      target="neu">Mozilla</a>
   </li>
   <li>
      <a href="http://www.opera.com/"
      target="neu">Opera</a>
   </li>
</ul>
</body>
</html>

Bilder

Abbildung 8.7     Alle Links werden im neuen Fenster geöffnet.


8.5.3 Ein Fenster öffnen und anpassen  

Der letzte Parameter ist gleichzeitig der interessanteste. Hier kann man das Aussehen des neuen Browserfensters etwas genauer anpassen. Neben der Höhe und Breite des Fensters kann man auch die meisten Leisten ein- und ausschalten. Es gibt hier zwei Arten von Parametern:

gpBilder
 
Numerische Werte: Beispielsweise die Höhe oder die Breite; diese haben das Format height=400.
gpBilder
 
Ja/Nein-Werte: Beispielsweise Statuszeile einblenden ja/nein. Die Werte yes und 1 oder die bloße Erwähnung der Option bedeuten »ja«, no und 0 bedeuten »nein«. Beispiel: status=yes,toolbar=no, menubar.

Sie können natürlich mehrere Parameter zusammen verwenden. Sie müssen diese dazu durch Kommata voneinander trennen, und Sie dürfen keine Leerzeichen verwenden! Der folgende Befehl öffnet ein Fenster, das 400 Pixel breit ist und eine Statuszeile hat:

var fenster = window.open("", "neu",
"width=400,status=1");

Die folgende Tabelle enthält alle an- bzw. ausblendbaren Elemente.

 

Tabelle 8.1     Die (booleschen) Optionen für window.open()

Option Beschreibung Besonderheiten
alwaysLowered Das Fenster befindet sich immer im Hintergrund an/aus Netscape; nur bei Verwendung von Signed Scripts (signierte Skripten)
alwaysRaised Das Fenster befindet sich immer im Vordergrund an/aus Netscape; nur bei Verwendung von Signed Scripts (signierte Skripten)
channelmode Anzeige der Channelleiste an/aus Internet Explorer
dependent Fensterabhängigkeit an/aus (wird das aufrufende Fenster geschlossen, so wird auch das geöffnete Fenster geschlossen) Netscape
directories Persönliche Symbolleiste (Netscape) bzw. Links-Leiste (Internet Explorer) an/aus
fullscreen Anzeigen des neuen Fensters im Vollbildmodus an/aus Internet Explorer
hotkeys Hotkeys (z.  B. Drucken: (Strg)+(P)) an/aus Netscape
location Adressleiste an/aus
menubar Menüleiste an/aus
personalbar Persönliche Symbolleiste an/aus Netscape; entspricht dort der Option directories
resizable Fenster in der Größe veränderbar an/aus
scrollbars Scrollleisten an/aus
status Statusleiste an/aus
titlebar Titelleiste an/aus Netscape; nur bei Verwendung von Signed Scripts (signierten Skripten)
toolbar Werkzeugleiste an/aus
z-lock Fenster verbleibt auch mit Fokus im Hintergrund an/aus Netscape; nur Signed Scripts (signierte Skripten)

 

Des Weiteren stehen die folgenden numerischen Elemente zur Verfügung:

 

Tabelle 8.2     Die (numerischen) Optionen für window.open()

Option Beschreibung Besonderheiten
height Höhe des Fensters mindestens 100 Pixel oder (unter Netscape) Signed Script (signiertes Skript)
width Breite des Fensters mindestens 100 Pixel oder (unter Netscape) Signed Script (signiertes Skript)
innerHeight Höhe des sichtbaren Browserbereichs (also ohne Symbolleisten, Scrollbalken etc.) Netscape
innerWidth Breite des sichtbaren Browserbereichs (also ohne Symbolleisten, Scrollbalken etc.) Netscape
outerHeight Höhe des Fensters Netscape; entspricht height
outerWidth Breite des Fensters Netscape; entspricht width
left x-Koordinate1 der linken oberen Ecke des Fensters Internet Explorer; muss im sichtbaren Bereich des Bildschirms liegen
top y-Koordinate1 der linken oberen Ecke des Fensters Internet Explorer; muss im sichtbaren Bereich des Bildschirms liegen
screenX x-Koordinate1 der linken oberen Ecke des Fensters Netscape; muss (ohne Signed Script/signiertes Skript) im sichtbaren Bereich des Bildschirms liegen
screenY y-Koordinate1 der linken oberen Ecke des Fensters Netscape; muss (ohne Signed Script/signiertes Skript) im sichtbaren Bereich des Bildschirms liegen

 

Wenn einer dieser Parameter nicht angegeben wird, nimmt der JavaScript-Interpreter an, er wäre auf no bzw. 0 gesetzt worden. Der folgende Aufruf erzeugt also ein ganz mageres Fenster:

var fenster = window.open("", "neu", "");

Aus Kompatibilitätsgründen sollten Sie zwischen den einzelnen Optionen – die Sie frei miteinander kombinieren können – keine Leerzeichen einsetzen.

Wie Sie in den vorangegangenen Beispielen gesehen haben, fehlt der dritte Parameter komplett. So sieht das neue Fenster gemäß den Standardwerten des Browsers aus. Beim den meisten modernen Browsern entsprechen die Ausmaße und angezeigten Leisten denen des zuletzt aktiven Browserfensters.

Auch bei einigen derjenigen Attribute, die (unter Mozilla-Browsern) keine signierten Skripten voraussetzen, kann unter bestimmten Voraussetzungen ein signiertes Skript verlangt werden:

gpBilder
 
bei Fenstern, deren Höhe oder Breite kleiner als 100 Pixel ist
gpBilder
 
bei einem Fenster, das vollständig oder größtenteils außerhalb des sichtbaren Bereichs liegt

Der Internet Explorer ignoriert diese Angaben stets. Wenn unter Mozilla die besonderen Rechte für ein signiertes Script nicht angefordert wurden, wird die Option ebenfalls ignoriert. Ein Versuch, ein Fenster ohne Titelleiste zu öffnen, führt bei beiden Browsern zu einem neuen Fenster, und zwar mit Titelleiste.

Wenn Sie unter Netscape die besonderen Fensteroptionen benötigen, müssen Sie zunächst die entsprechenden Rechte vom Benutzer anfordern:

netscape.security.PrivilegeManager.enablePrivilege(
    "UniversalBrowserWrite");
window.open("", "", "width=50,height=50");
netscape.security.PrivilegeManager.disablePrivilege(
    "UniversalBrowserWrite");

Damit das überhaupt funktioniert, muss Java im Browser aktiviert sein, da der Privilege Manager auf Java-Basis arbeitet.

Wenn der Benutzer die Sicherheitsabfrage akzeptiert, wird tatsächlich ein 50 Pixel hohes Fenster geöffnet – nur ist es ein wenig breiter als 50 Pixel, da die drei Windows-Schaltflächen zum Minimieren, Maximieren und Schließen des Fensters zu viel Platz wegnehmen. Um ein wirklich 50*50 Pixel großes Fenster zu erhalten, müssen Sie zusätzlich noch die Titelleiste ausblenden:

netscape.security.PrivilegeManager.enablePrivilege(
    "UniversalBrowserWrite");
window.open("","", "width=50,height=50,titlebar=no");
netscape.security.PrivilegeManager.disablePrivilege(
    "UniversalBrowserWrite");

Wie Sie im Browser sehen können, ist es eine gute Idee der Mozilla-Entwickler gewesen, bei der Verwendung dieser Fensteroptionen die Zustimmung des Benutzers einzuholen. Das neue Fenster ist kaum mehr sichtbar.

Kehren wir zu einer der eingangs erwähnten Anwendungsmöglichkeiten zurück: zur Anzeige eines nervigen Werbebanners. Wenn Ihr Werbebanner eine Breite von 200 × 100 Pixeln hat, könnte Ihr Aufruf folgendermaßen aussehen:

Unter UNIX kann die Größe eines Fensters über X-Ressourcen bestimmt werden, die immer Priorität haben.

Die Datei banner.html kann folgendermaßen aussehen (Sie benötigen zusätzlich noch eine Bannergrafik banner.gif):

<html>
<head>
<title>Banner</title>
</head>
<body
   topmargin="0" leftmargin="0"
   marginwidth="0" marginheight="0">
   <!-- kein Abstand zum Fensterrand -->
<a href="http://www.ihranzeigenkunde.de/"
target="_blank">
<img src="banner.gif" width="200" height="100"
border="0" />
</a>
</body>
</html>

Man kann es nicht oft genug erwähnen: Aus Sicherheitsgründen muss ein mit JavaScript geöffnetes Fenster mindestens 100 Pixel hoch und 100 Pixel breit sein. Wenn Sie also für Höhe oder Breite einen Wert kleiner hundert angeben, wird das Fenster trotzdem 100 Pixel breit oder hoch dargestellt. Mit Mozilla-Browsern lässt sich das (sehr mühsam) umgehen, indem man signierte Skripten nutzt. Ebenso können Sie (mit screenX/screenY) ein Fenster nicht vollständig aus dem sichtbaren Bereich hinaus verschieben, wenn Sie kein signiertes Skript verwenden.

Mit der folgenden HTML-Seite können Sie einige Parameter für das Aussehen des neuen Fensters anpassen. Details dazu (und ein ausführlicheres Beispiel) erhalten Sie im nächsten Kapitel, in dem die Auswertung von Formulardaten behandelt werden wird.

<html>
<head>
<title>Fenster-Test</title>
<script type="text/javascript"><!--
function neuesfenster(formular) {
   var optionen = "width=400,height=300";
   for (var i=0; i<formular.elements.length; i++) {
      if (formular.elements[i].checked) {
         optionen += "," + formular.elements[i].name;
   }
      }
   var fenster = window.open("", "neu", optionen);
   if (fenster != null) {
      with (fenster.document) {
         open();
         write("<" + "html" + "><" + "body" + ">");
         write("Neues Fenster mit folgenden Optionen:"
         +optionen);
         write("<" + "hr" + " />");
         write("<"+"a href='javascript:window.close()'"+">");
         write("Fenster schließen<" + "/a" + ">");
         write("<" + "/body" + "><" + "/html" + ">");
         close();
      }
   }
}
//--></script>
</head>
<body>
<h1>Fenster-Optionen auswählen</h1>
<form>
<input type="checkbox" name="dependent" /> dependent<br />
<input type="checkbox" name="directories" />
directories<br />
<input type="checkbox" name="hotkeys" /> hotkeys<br />
<input type="checkbox" name="location" /> location<br />
<input type="checkbox" name="menubar" /> menubar<br />
<input type="checkbox" name="scrollbars" /> scrollbars<br />
<input type="checkbox" name="status" /> status<br />
<input type="checkbox" name="toolbar" /> toolbar<br />
</form>
<a href="javascript:neuesfenster(document.forms[0]);">Fenster erzeugen</a>
</body>
</html>

Bilder

Abbildung 8.8     Die verschiedenen Fenstereigenschaften können direkt ausprobiert werden.

Beachten Sie bei dem Listing, dass in das neue Fenster neben den Optionen auch ein Link zum Schließen des Fensters geschrieben wird:

<a href="javascript:window.close();">Fenster schließen</a>

Das Fenster kann natürlich auch vom aufrufenden Skript aus geschlossen werden; verwenden Sie dazu die Referenz auf das neue Fenster, die von window.open() zurückgegeben wird; in unserem Beispiel also fenster. close().

Ein kurzes Wort noch zu der Zeile if (fenster != null): Es kann sein, dass das Öffnen des neuen Fensters nicht funktioniert hat; insbesondere der Internet Explorer gibt bei wenig freiem Speicher gern eine Fehlermeldung aus und öffnet das Fenster dann nicht.

Anwendungen für die neuen JavaScript-Fenster gibt es viele: Beispielsweise könnten Sie auf Ihren Webseiten eine Hilfefunktion anbieten. Der Hilfetext kann dann in einem neuen Fenster (ohne Platz raubende Symbolleisten) dargestellt werden; dies ist insofern praktisch, als der Benutzer nicht auf die Zurück-Schaltfläche seines Browsers klicken muss, um wieder zu der Seite zurückzukehren, auf der er die Hilfe in Anspruch nehmen wollte.


8.5.4 Modale Fenster 
topBilder

Ein so genanntes modales Fenster ist die gierige Variante von neuen Fenstern. Das aufrufende Fenster ist praktisch inaktiv, Sie können darauf erst wieder zugreifen, wenn das neue, modale Fenster wieder geschlossen worden ist. Sie haben diese Art von Fenstern schon kennen gelernt, sie werden beispielsweise durch window.alert(), window.confirm() und window.prompt() erzeugt. Die Gestaltungsmöglichkeit dieser Fenster war ja relativ gering, aber ab Browsern der Versionsnummer 4 gibt es Alternativen.

Für Mozilla-Browser gibt es die Fenstereigenschaft alwaysRaised, aber die funktioniert nur in Zusammenarbeit mit so genannten signierten Skripten (siehe dazu auch Kapitel 29). Ab dem Internet Explorer 4 gibt es für Benutzer des Microsoft-Browsers die Möglichkeit, ein modales Fenster zu erzeugen. Die dazugehörige Methode des Fenster-Objekts heißt showModalDialog(), und in der folgenden Tabelle sehen Sie die dazugehörigen Fenstereigenschaften:

Tabelle 8.3     Fensteroptionen für modale Fenster

Option Typ Beschreibung
center Ja/Nein Das neue Fenster wird zentriert dargestellt (Standard).
dialogHeight numerisch Höhe des Fensters in Pixeln
dialogLeft numerisch Abstand vom linken Bildschirmrand in Pixeln
dialogTop numerisch Abstand vom oberen Bildschirmrand in Pixeln
dialogWidth numerisch Breite des Fensters in Pixeln
help Ja/Nein Ein Hilfesymbol (Fragezeichen) wird angezeigt (Standard) bzw. nicht angezeigt.
status Ja/Nein Die Statuszeile wird ein- (Standard) oder aus-geblendet.
resizeable Ja/Nein Die Größe des Fensters kann vom Benutzer ge-ändert bzw. nicht geändert (Standard) werden.

 

Der folgende Code öffnet also ein modales Fenster im Internet Explorer. Sie können dort beispielsweise einen Hilfetext anzeigen. Wie immer der Warnhinweis: Da dieser Code nur mit dem Internet Explorer funktioniert, sollten Sie darauf achten, dass man in Ihren Seiten auch ohne die modalen Fenster navigieren kann – außer natürlich, Sie operieren in einem Intranet und die Firmenpolitik verbietet Netscape-Browser (solche Firmen gibt es immer häufiger).

<script language="JavaScript"><!--
var fenster = window.showModalDialog("", "Modal",
"dialogHeight=300,dialogWidth=400,status=no,resizeable");
//--></script>

8.6 Fernsteuerung 
topBilder

Wie Sie vom aufrufenden Fenster aus auf das neue Fenster zugreifen können, wissen Sie jetzt. In die andere Richtung ist das genauso einfach.

Schon seit JavaScript 1.1 gibt es die Fenster-Eigenschaft opener , die eine Referenz auf das öffnende Fenster darstellt. Sogar mit JavaScript 1.0 kann man sie jedoch relativ einfach nachbilden. Auch wenn das heutzutage nicht mehr relevant ist, zeigt es dennoch, wie Sie Eigenschaften von Objekten in JavaScript dynamisch setzen können. Setzen Sie also die Eigenschaft opener des neuen Fensters, sofern sie gleich null ist, auf das aktuelle Fenster (also self):

<script type="text/javascript"><!-- var fenster = window.open("seite.htm", "neu"); if (fenster.opener == null) { fenster.opener = self; } //--></script>


8.6.1 Links mit JavaScript  

Über die Eigenschaft opener ist es möglich, auf das ursprüngliche Fenster zuzugreifen. Im Folgenden soll eine Fernsteuerung entwickelt werden. Ausgangspunkt ist folgendes Frameset:

<html> <head> <title>Fernsteuerung</title> <script type="text/javascript"><!-- function inhalt() { return "<" + "html" + "><" + "/html" + ">"; } //--></script> </head> <frameset rows="100,*"> <frame src="navi.html" name="navigation" /> <frame src="javascript:top.inhalt()" /> </frameset> <noframes> <body>Ihr Browser kann mit Frames nichts anfangen!</body> </noframes> </html>

Die Datei navi.html sieht folgendermaßen aus:

<html> <head> <script type="text/javascript"><!-- function fernsteuerung() { var fenster = window.open("remote.html", "fern", "height=200,width=400,status=1"); if (fenster.opener == null) { fenster.opener = self; } } //--></script> </head> <body> <a href="javascript:fernsteuerung();">Fernsteuerung öffnen</a> </body> </html>

Es passiert also nichts Weltbewegendes: Durch den Klick auf den Link wird ein neues Fenster mit der Datei remote.html geladen. Diese sieht wie folgt aus:

<html> <head> <title>Fernsteuerung</title> <script type="text/javascript"><!-- function lade(seite) { //kommt noch... } //--></script> </head> <body> <h3>Meine Lieblingslinks</h3> <ul> <li> <a href="javascript:lade( 'http://www.microsoft.com/')">Microsoft</a> </li> <li> <a href="javascript:lade( 'http://www.mozilla.com/')">Mozilla</a> </li> <li> <a href="javascript:lade( 'http://www.opera.com/')">Opera</a> </li> </ul> <a href="javascript:window.close();">Fenster schließen</a> </body> </html>

In der Funktion lade() muss die übergebene URL in den unteren Frame der Beispielseite geladen werden. Mit der Eigenschaft window.opener hat man eine Referenz auf den oberen Frame, und – wie in Kapitel 10 gezeigt werden wird – man kann dann auf den unteren Frame zugreifen:

function lade(seite) { if (window.opener != null) { window.opener.parent.frames[1].location.href = seite; } }


8.6.2 Links ohne JavaScript 
topBilder

Eigentlich ist dieses Vorgehen zu umständlich. Man kann auch mit ordinären HTML-Links arbeiten. Als target-Attribut gibt man den Namen des Frames bzw. des Fensters an, in den bzw. in das die neue Seite geladen werden soll.

Im obigen Beispiel wurde jedoch aus Versehen kein Name für den Frame angegeben; bei Fenstern haben Sie ja ohnehin standardmäßig keinen Namen. Mit JavaScript lässt sich dieser Name jedoch ganz einfach vergeben; die entsprechende Eigenschaft heißt name.

Ändern Sie also die Funktion fernsteuerung() folgendermaßen ab:

function fernsteuerung() { var fenster = window.open("remote.html", "fern", "height=200,width=400,status=1");

self.name = "Ziel";

if (fenster.opener == null) { fenster.opener = self; } }

Die Fernsteuerung besteht dann aus (beinahe) reinem HTML-Code:

<html> <head> <title>Fernsteuerung</title> </head> <body> <h1>Meine Lieblingslinks</h1> <ul> <li> <a href="http://www.microsoft.com/" target="Ziel">Microsoft</a> </li> <li> <a href="http://www.mozilla.com/" target="Ziel">Mozilla</a> </li> <li> <a href="http://www.opera.com/" target="Ziel">Opera</a> </li> </ul> <a href="javascript:window.close();">Fenster schließen </a> </body> </html>


8.7 Fenster schließen 
topBilder

Wie Sie bereits gesehen haben, kann ein Fenster mit Fensterreferenz. close() geschlossen werden. Es gibt jedoch eine Einschränkung: Laden Sie doch einmal folgende HTML-Seite in Ihren Browser:

<html> <head> <title>window.close()</title> </head> <body> <script type="text/javascript"><!-- window.close(); </script> </body> </html>

Bilder

Abbildung 8.9     Warnmeldung beim Schließen eines Fensters, das nicht mit JavaScript geöffnet worden ist

Sie sollten eine Warnung erhalten; in manchen Browsern (etwa Firefox) erscheint lediglich eine Fehlermeldung in der JavaScript-Konsole. Das wäre ja auch noch schöner, wenn man mit JavaScript jedes beliebige Fenster schließen könnte! Fenster, die mit JavaScript geöffnet wurden, können jedoch problemlos geschlossen werden, wie Sie im vorigen Abschnitt ja schon gesehen haben.


8.7.1 Andere Fenster schließen 
topBilder

Etwas komplizierter ist es jedoch, wenn ein anderes Fenster geschlossen werden soll. Angenommen, der Benutzer schließt das Fenster mit der systemspezifischen Tastenkombination (unter Windows beispielsweise mit (Alt)+(F4)). Die Variable, in der eine Referenz auf das Fenster abgespeichert ist, verschwindet dadurch ja nicht. Ist das Fenster also schon geschlossen, würde Fensterreferenz.close() eine Fehlermeldung ausgeben.

Die Fernsteuerung soll so abgeändert werden, dass sie von der Hauptseite aus wieder geschlossen werden kann. JavaScript unterstützt die Fenstereigenschaft closed, einen booleschen Wert, der angibt, ob das Fenster noch offen ist oder nicht. Somit kann die Datei navi.html folgendermaßen geändert werden, damit die gewünschte Funktionalität sichergestellt wird:

<html> <head> <script type="text/javascript"><!-- var fenster //Variable muss global sein! function fernsteuerung() {

fenster = window.open("remote.html", "fern", "height=200,width=400,status=1");

self.name = "Ziel"; if (fenster.opener == null) { fenster.opener = self; } }

function schliessen() { if (fenster && !fenster.closed) { fenster.close(); } }

//--></script> <body> <a href="javascript:fernsteuerung();"> Fernsteuerung öffnen</a><br/>

<a href="javascript:schliessen();"> Fernsteuerung schließen</a>

</body> </html>

Das Kernstück ist die Abfrage if (fenster && !fenster.closed). Wie Sie bereits wissen, werden boolesche Ausdrücke in JavaScript von links nach rechts ausgewertet. Wurde also noch kein Fenster geöffnet, wird der rechte Teil der Bedingung gar nicht mehr überprüft und es erscheint auch keine Fehlermeldung. Falls schon einmal ein Fenster geöffnet wurde, wird der rechte Teil überprüft. Ist die Eigenschaft fenster. closed gleich false, muss das Fenster noch offen sein, also wird es geschlossen.

 

8.8 Fenster bewegen mit JavaScript 
topBilder

Prinzipiell gibt es zwei Möglichkeiten, ein Fenster zu bewegen, und das ist reine Definitionssache. Entweder wollen Sie das gesamte Fenster irgendwohin bewegen, oder Sie wollen den Inhalt des Fensters scrollen. Beides ist mit neueren Browsern möglich und wird an dieser Stelle kurz vorgestellt.


8.8.1 Fenster verschieben  

Eine häufig gestellte Frage lautet: Wie kann ich das Browserfenster zentrieren? Andere Leute wiederum möchten, dass das Browserfenster maximiert oder minimiert wird (so viel vorweg: Das ist nicht möglich) oder dass es sich am oberen Bildschirmrand befindet. Dies ist kein aufwändiges Verfahren, es müssen einfach entsprechende Eigenschaften des window-Objekts gesetzt oder ausgelesen oder Methoden aufgerufen werden. Übertreiben Sie es jedoch nicht mit diesen Effekten. Viele Webbesucher reagieren ziemlich giftig, wenn man ihnen vorschreiben will, wo sich ein Fenster befindet.

Moderne Browser können ein Fenster verschieben, und zwar sowohl an eine bestimmte Position als auch um einen gewissen Wert. Dazu gibt es zwei Methoden:

gpBilder
 
window.moveTo(x, y): Verschiebt das Fenster so, dass die linke obere Ecke die Koordinaten (x, y) hat. Es handelt sich hier um eine absolute Verschiebung. Sie können das Fenster damit nicht aus dem sichtbaren Bereich hinaus verschieben, außer Sie verwenden signierte Skripten (die werden in Kapitel 29 behandelt).
gpBilder
 
window.moveBy(x, y): Verschiebt das Fenster horizontal um x Pixel, vertikal um y Pixel, führt also eine relative Verschiebung durch. Auch hier kann das Fenster nicht aus dem sichtbaren Bereich hinaus verschoben werden.

Erinnern Sie sich noch an die Auflistung der Parameter für window. open()? All diese Parameter sind auch gleichzeitig Eigenschaften für das window-Objekt. Somit werden beispielsweise mit window.outerHeight und window.outerWidth die Ausmaße des Browserfensters angegeben.

Um nun die Maximierung eines Fensters zu simulieren (man führt damit nicht die API-Funktion für die Fenstermaximierung aus, sondern vergrößert das Fenster nur entsprechend), muss man noch die Ausmaße des Bildschirms bestimmen. In JavaScript kann man diese Werte aus dem screen-Objekt erhalten:

gpBilder
 
screen.availWidth enthält die Bildschirmbreite.
gpBilder
 
screen.availHeight enthält die Bildschirmhöhe.

Eine Funktion zum Maximieren des Fensters sieht also folgendermaßen aus: Die linke obere Ecke des Fensters wird zunächst an die linke obere Ecke des Bildschirms gesetzt, und dann wird das Fenster entsprechend vergrößert.

function maximieren() {
   window.moveTo(0, 0);
   window.outerHeight = screen.availHeight;
   window.outerWidth = screen.availWidth;
}


8.8.2 Fensterinhalt scrollen 
topBilder

Bereits in JavaScript Version 1.1 wurden Methoden zum Scrollen des Fensterinhalts eingeführt. Die dazugehörige Methode heißt window.scroll(x, y). Sie scrollt den Fensterinhalt an die angegebenen Koordinaten. Es ist eigentlich unlogisch, dass das Scrollen eine Methode des window-Objekts ist, da ja nicht das Fenster gescrollt wird, sondern das Dokument, das sich darin befindet. Auch hier gilt: Übertreiben Sie es nicht. Der Benutzer ärgert sich immer, wenn er das Gefühl hat, nicht die Kontrolle über ein Fenster zu besitzen. Scrollen Sie also nur dann, wenn es wirklich Sinn macht.

Eine der möglichen Anwendungen besteht darin, nach oben zu scrollen. Auf vielen längeren Webseiten finden Sie einen Link, der nach oben scrollt – Sie ersparen Ihren Benutzern so die Mühe, mit der Maus den Scrollbalken zu treffen. Dieser Effekt wird meistens so angeboten:

<a href="#top">nach oben</a>

Am Anfang des Dokuments befindet sich eine Textmarke namens "top", zu der dann gescrollt wird. Das ist ein netter Effekt, vor allem bei längeren Dokumenten. Zum einen jedoch ändert sich die URL – was Neulinge immer stark irritiert, man glaubt es kaum –, und zum anderen ist es bei komplexeren Dokumenten nicht immer möglich, ganz oben eine Textmarke unterzubringen. Wenn beispielsweise direkt nach dem <body>-Tag ein Werbebanner eingefügt wird (manche Gratis-Hoster machen das so), kann man nie nach ganz oben scrollen.

Das Scrollen an den Dokumentenanfang geht ganz bequem. Es muss einfach zu den Koordinaten (0, 0) gescrollt werden:

<a href="javascript:window.scroll(0, 0)">nach oben</a>

In JavaScript 1.2 wurden zwei neue Methoden eingeführt. Dabei verhält sich window.scrollTo(x, y) genauso wie window.scroll(x, y), während window.scrollBy(x, y) neu ist: Ebenso wie bei window.moveBy(x, y) wird hier relativ gescrollt.

Die Methoden zum Scrollen werden im Zusammenhang mit der exakten Positionierung von HTML-Dokumenten bei DHTML noch interessant werden; fürs Erste aber sollte dieser Einblick genügen.

 

Das Tutorial ist ein Auszug aus der 7. Auflage des Buches von Christian Wenz:

JavaScript und Ajax - Das umfassende Handbuch
Galileo Computing, 853 Seiten, 8. aktualisierte Auflage

Die Veröffentlichung des Kapitels erfolgt mit freundlicher Genehmigung von Galileo Press.

Mehr Informationen zum aktualisierten Fachbuch für Webentwickler gibt es hier: JavaScript und Ajax
 
Alle Kapitel des Buches:
1 Grundlagen
2 JavaScript-Praxis
3 Professionelles JavaScript
4 Web 2.0 und Ajax
5 Kommunikation
6 Serverseitige Programmierung
7 Sicherheit
8 Praxis
9 Anhang
Bilder


 

Kommentare
Achtung: Du kannst den Inhalt erst nach dem Login kommentieren.
Portrait von Pictureboy28
Portrait von skyflight1981
x
×
×