Manchmal werden Variablen erst im Laufe des Programms angelegt und nicht schon beim Start. Wenn man dann auf eine solche Variable zugreift, diese aber noch nicht angelegt wurde, kommt es zur Fehlermeldung, daß die Variable nicht definiert sei, und das Skript bleibt stehen. Beispiele solche Fehlermeldungen auslösende Aufrufe:
alert (variable)
oder auch:
if (variable)
Aber es gibt es die Möglichkeit, vor der Benutzung einer Variable vorher deren Existenz abzufragen, und zwar über den Umweg über ein Objekt. Dann tritt keine Fehlermeldung mehr auf. Man setzt also einfach einen Objektnamen davor (z. B. window oder self) und fragt dann die Variable über das Objekt ab. Beispiel:
if (window.variable) alert (variable) // Variable existiert + hat Inhalt
Allerdings muß die Variable auch einen Inhalt haben, leere Strings, Zahlenwerte 0 oder Boolean-Variablen "false" funktionieren nicht, da die if-Abfrage dann ebenfalls false zurückliefert, so als würde die Variable nicht existieren.
Der direkte Zugriff auf die Variable geht nicht, siehe oben "if (variable)", da kommt es wieder zur Fehlermeldung und Programm-Abbruch, wenn die Variable noch nicht angelegt ist.
Sinnvoll ist die Existenzüberprüfung vor allem bei Frame-übergreifender Programmierung, wenn man nicht weiß, welches Dokument im anderen Frame geladen ist, ob das Dokument überhaupt schon geladen ist und ob die gewünschten Objekte vorhanden sind. So hat z. B. jedes Dokument einen Wert namens document.lastModiefied, allerdings nicht die von cgi-Skripten generierten Seiten. Würde man nun z. B. in einem Menü-Frame das Änderungsdatum der Hauptseite anzeigen lassen, würde es bei der Anzeige von cgi-Skriptausgaben zu einer Fehlermeldung kommen. Diese läßt sich dann abfangen, z. B.
if (parent.MainFrame.document) if (parent.MainFrame.document.lastModified) ... // Ausgabe
Nach einem Reload (Fenster aktualisieren) wird die Seite neu geladen und alle Variablen haben wieder den Anfangswert. Das gleiche gilt bei Benutzung der Browser-Schaltflächen Vor und Zurück. Die einzige Variable, die nicht zurückgesetzt wird, ist window.name. Hierin läßt sich ein Textstring speichern. Darin kann man sich eine oder mehrere wichtige Variablen retten. Mehrere Variablen dadurch, daß man die Inhalte aneinanderkettet und später wieder auseinanderklamüsert. Als Trennzeichen empfiehlt sich das "&" (wird auch in URL-Parametern dafür verwendet).
Zur Beachtung: Die Name-Eigenschaft wird nur beim eigentlichen Fenster nicht gebraucht, bei Frames enthält sie dagegen den Framenamen. Würde man diesen ändern, würden die Links aus anderen Frames nicht mehr in diesem angezeigt werden können, sondern stattdessen in einem neuen Fenster geöffnet werden. Daher sollte man immer nur top.name ändern. Außerdem wird der Fenstername benötigt, wenn man von anderen Fenstern darauf zugreifen will (z. B. Navigations-Fernsteuerung), daher sollte man den Fensternamen nur dort verändern, wo er sonst nicht mehr benötigt wird.
Demonstration:
Fensternamen anzeigen: javascript:alert(top.name) (zu Anfang leerer String)
Fensternamen ändern: javascript:void(top.name="Test")
Fenster aktualisieren: javascript:top.location.reload() (Achtung: danach wieder auf JavaScript > Sonstiges > Sonstiges klicken.)
// Inhalt von changeframes.js:
function changeFrames() // paarweise Parameter: Frame, URL. Wenn Frame == "" dann aktuellen Frame.
{
for (var i=0; i<changeFrames.arguments.length-1; i+=2)
{
var frame = changeFrames.arguments[i]
if(!frame)
frame = this.name
parent.frames[frame].location.href = changeFrames.arguments[i+1]
}
}
/*
Einbinden in HTML-Datei mit:
<Script Type="text/javascript" Src="js/changeframes.js"></Script>
Im Pfad "../" voransetzen wenn Aufruf aus Unterordner.
"js/" weglassen wenn Unterordner nicht vorhanden
Empfehlung ist aber, diesen im Hauptverzeichnis anzulegen.
Aufruf-Beispiel:
<A Href="javascript:changeFrames('','frame1.htm','Frame2','frame2.htm')">Ursprungsanordnung</A>
Als Frame kann der bei <frame name="..."> im <Frameset> angegebene Name angegeben werden
(in Hochkomma, da Anführungszeichen schon in Href verwendet werden),
oder '' für aktuellen Frame,
oder die laufende Nummer nach der Reihenfolge der <frame>-Tags in <frameset>, ab 0 gezählt.
Es kann eine beliebige Anzahl Parameter eingegeben werden: Frame, URL, Frame, URL, ...
*** Ein Service von http://www.bitwelt.de ***
*/
In JavaScript gibt es aus gutem Grunde keine Warteschleifen-Funktion: sie erzeugen maximale Systemauslastung, der Rechner geht in die Knie, nichts geht mehr. Dafür gibt es aber die Möglichkeit, Timer zu setzen. Dadurch wird das System entlastet, aber der Denkaufwand beim Programmieren ist bedeutend höher. Manchmal erscheint es sogar so, als ob es mit dem Timer nicht gehen würde, z. B. wenn eine Funktion einen Wert zurückgeben soll, aber damit noch warten soll. Dann muß vorläufig ein Wert zurückgegeben werden, der zum Abbruch der gewünschten Funktion führt, und später die Funktion mit einem Wert aufgerufen werden, der zum Ausführen der Funktion führt. Beispiel: <form onsubmit="return checkAll()">, dann muß die Funktion checkAll() vorläufig false zurückgeben, aber vorher noch einen Timer setzen mit "MeinFormular.submit()" als später auszuführender Befehl.
Aber wer mit den Timern nicht zurecht kommt und stattdessen wie gewohnt eine Warteschleife benutzen will, kann folgende Funktion zur Erzeugung der Warteschleife nutzen. Wenn dann später einmal die Programmierung steht, sollte sie aber durch Timeraufrufe ersetzt werden.
function Wait(zeit) // Warteschleife einlegen, zeit in ms
// Nur für Testzwecke. Erzeugt unnötigerweise maximale Systemauslastung.
// In endgültiger Version durch Timeraufrufe ersetzen:
// Teil nach wait in eigene Funktion packen, z. B. afterwait(), setTimeout("afterwait()",zeit).
// Bei Rückgabewerten zuerst abbrechen,
// dann später die durch den Rückgabewert veranlasste Funktion separat aufrufen.
// Beispiel: <form onSubmit="return checkAll()">, in checkAll am Ende:
// setTimeout("MeinFormularName.submit()",1000); return false();
{
var start=new Date().getTime()
do
{
var jetzt=new Date().getTime()
// alert("Test\nStart: "+start+"\nJetzt: "+jetzt+"\nZeit: "+zeit+"\nSumme: "+start+zeit)
} while(jetzt<start+zeit)
}