Coding-Schatzkästlein
Kleine Tips & Scripts zum Webdesign
Start > JavaScript > Systemvariable

JavaScript: Systemvariable "SysVars"
(mit Fehler- & (IE-)Linkrahmen-Unterdrückung, sowie "Resize-Aktualisierung")

Zusammenfassung

Name:  SysVars
Aufgabe:  Funktion, um verschiedene Systemvariable (Hardware, Browser & Dokument) zu ermitteln. Stellt außerdem Routinen zur Unterdrückung des gestrichelten Linkrahmens und zur Seiten-Aktualisierung bei Änderung der Browsergröße zur Verfügung.
Benötigt:  JavaScript 1.0, teilweise auch höhere Versionen (gesichert)
Beispiel:  alertSysVars()
parent.alertSysVars()
top.alertSysVars()
MagicHTML
MagicHTML-Test
Download:  sysvars.zip

Hiermit werden verschiedene Systemvariable zur Verfügung gestellt, mit denen man seine Seiten flexibler gestalten kann. Der Aufruf erfolgt mit SysVarsHead(offlineDir,defaultFile) (wird automatisch beim Laden des externen Scripts aufgerufen). Die zwei - für eine komplette Website einheitlichen - Parameter sind notwendig, damit die Variablen bezügl. Dateipfad & -namen sowohl online wie auch offline korrekt gesetzt werden können:

  1. offlineDir muß den Namen des lokalen Verzeichnisses haben, in dem die HTML-Dateien liegen. Ist z.B. die Homepage auf der Festplatte die Datei "E:\Server-Dateien\Server1\index.htm" so wäre für offlineDir die Zeichenfolge "Server1" zu übergeben
  2. defaultFile muß den Namen der Datei haben, die auf dem Server als "Default-Datei" aufgerufen wird (die Datei, die geladen wird, wenn der Surfer keine Datei angibt - i.d.R. "index.html", "index.htm" oder "default.html"). Lädt der Browser nach Eingabe von "www.meinserver.de" also "www.meinserver.de/index.htm", so wäre für defaultFile die Zeichenfolge "index.htm" zu übergeben

Nach dem Aufruf von SysVarsHead() sind alle Systemvariablen existent, einige Werte können allerdings erst mit separaten Funktionen korrekt ermittelt werden: Die Größe von Browserfenster & Dokument sind beim Internet Explorer erst nach Vorhandensein des BODY-Tags abrufbar, weswegen diese Systemvariablen erst zu einer späteren Zeit mit SysVarsBody() korrekt gesetzt werden können. Die Geschwindigkeit der Internetverbindung wird mit SysVarSpeed() bestimmt - der Aufruf sollte erst nach dem eigentlichen Laden der Seite erfolgen, damit der Wert möglichst unverfälscht ist. Die einzelnen Systemvariablen:

  • Verwendeter Browser (String):
    • agt_os (Betriebssystem des Browsers: Windows, Macintosh, Linux/Unix, OS/2)
    • agt_lang (Sprache des Browsers: de, en, en-US, ...)
  • Verwendeter Browser (Number):
    • agt_version (Versionsnummer des Browsers - ggf. nur die "Mozilla-kompatible")
    • agt_major (Hauptversionsnummer des Browsers - ggf. nur die "Mozilla-kompatible")
    • agt_ieVersion (IE-Versionsnummer)
    • agt_opVersion (Opera-Versionsnummer)
    • agt_safVersion (Safari-Versionsnummer)
    • agt_kqVersion (Konqueror-Versionsnummer)
    • agt_jsVersion (JavaScript-Versionsnummer)
    • agt_speed (Geschwindigkeit der Internetverbindung - erst mit SysVarSpeed())
    • agt_colors (Anzahl der möglichen Browserfarben)
    • agt_width (Breite des Browserfensters - erst mit SysVarsBody())
    • agt_height (Höhe des Browserfensters - erst mit SysVarsBody())
    • agt_maxWidth (maximale Breite des Browserfensters)
    • agt_maxHeight (maximale Höhe des Browserfensters)
    • agt_screenWidth (Breite des Bildschirms)
    • agt_screenHeight (Höhe des Bildschirms)
    • agt_docWidth (Breite der Browser-Anzeigefläche - erst mit SysVarsBody())
    • agt_docHeight (Höhe der Browser-Anzeigefläche - erst mit SysVarsBody())
  • Verwendeter Browser (Boolean: true oder false):
    • is_ie (Browser Internet Explorer?)
    • is_ieSafer (Browser Internet Explorer 6/SP2 oder höher?)

      Anmerkung: Mit dem Service Pack 2 hat sich beim IE 6 einiges verändert! So kennt der IE ab diesem Zeitpunkt z.B. das Pseudoprotokoll view-source: nicht mehr. Oder er nimmt standardmäßig keine URLs in der Form http://user:password@example.com mehr an. Allerdings basiert die Erkennung momentan einzig auf dem User-Agent-String, was prinzipiell nicht sicher ist.

    • is_oldie (alter Internet Explorer (3.x)?)
    • is_nav (Browser Navigator/Mozilla?)
    • is_nav2 (Navigator 2?)
    • is_nav3 (Navigator 3?)
    • is_oldnav (alter Navigator (<=4.x)?)
    • is_op (Browser Opera?)
    • is_oldop (alter Opera (<=8.x)?)
    • is_saf (Browser Safari?)
    • is_kq (Browser Konqueror?)
  • Spezielle Browsereigenschaften (Boolean: true oder false):
    • is_w3cDOM (striktes W3C-DOM?)
    • is_w3cxDOM (erweitertes W3C-DOM?)
    • is_ieDOM (Internet-Explorer-DOM?)
    • is_nnDOM (Netscape-Navigator-DOM?)
    • is_external (IE-Browsererweiterungen vorhanden?)
    • is_noscript (NOSCRIPT-Tag vorhanden?)
    • is_complete (Browser erkennt Ladezustand von Images?)
    • is_connected (Browser hat Online-Verbindung?)
  • Spezielle Dokumenteneigenschaften (String):
    • doc_time (Aktuelles Datumsobjekt)
    • doc_Server (Dokumentenserver)
    • doc_TLDomain (Top-Level-Domain des Dokumentenservers)
    • doc_Domain (Hauptdomain des Dokumentenservers)
    • doc_Subdomain (alle Subdomains des Dokumentenservers)
    • doc_User (Aufrufender User)
    • doc_Password (User-Passwort)
    • doc_fullFile (Dateipfad & -name)
    • doc_File (Dateiname inkl. Dateiextension)
    • doc_FileName (Dateiname ohne Dateiextension)
    • doc_FileExt (Dateiextension)
    • doc_Path (Dateipfad)
    • doc_rootPath (relativer Pfad zur Root-Ebene)
    • doc_localPath (Pfad von Path auf der Festplatte)
    • doc_MainDir (Hauptverzeichnis der Datei; 1. Ebene von Path)
    • doc_FileDir (Verzeichnis der Datei; letzte Ebene von Path)
    • doc_Referrer (aufrufender URI)
    • doc_xServer (aufrufender Fremdserver)
    • doc_xTLDomain (Top-Level-Domain des aufrufenden Fremdservers)
    • doc_xDomain (Hauptdomain des aufrufenden Fremdservers)
    • doc_xSubdomain (alle Subdomains des aufrufenden Fremdservers)
    • doc_Search (übergebene Parameter)
    • doc_cachedURL (wenn Seite aus dem Google-Cache: URL des Originals)
  • Spezielle Dokumenteneigenschaften (Number):
    • doc_PathDeep (Anzahl der Unterverzeichnisse/Pfadtiefe)
    • doc_width (Breite des Dokumentenbereichs - erst mit SysVarsBody())
    • doc_height (Höhe des Dokumentenbereichs - erst mit SysVarsBody())
  • Spezielle Dokumenteneigenschaften (Boolean: true oder false):
    • is_online (Dokument vom Server geholt?)
    • is_cached (Dokument aus Google-Cache geladen?)
    • is_xcall (Dokument von fremder Seite aufgerufen?)
    • is_icall (Dokument von eigener Seite aufgerufen?)
    • is_refblocked (wurde Aufruferkennung verschleiert?)
    • is_frame (Dokument ist ein Frame?)
  • Außerdem:
    • doc_temp (leere Variable, z.B. fuer frameübergreifende Werteübergabe)
  • Dokumentensteuerung (zu setzen, Boolean: true oder false):
    • do_ceh (Fehlerunterdrückung erlaubt?)
    • do_resize (Seiten nach Größenänderung neuladen?)
    • do_deFocus (aktiviertes Element defokussieren/inaktivieren?)
    • do_frameset (Frameset nachladen?)
    • do_uncache (Original-Seite nachladen?)
    • do_blending (Dokumenten-Überblendung?)

Die verwendeten Sprachen sind verschiedene JavaScript-Versionen. Da der Code aber gesichert ist (es wird überprüft, ob die jeweils benötigten Funktionen überhaupt vorhanden sind), funktioniert er bereits fehlerfrei ab JavaScript 1.0. Variablen, die aufgrund der JavaScript-Version des Browsers nicht ermittelt werden können, können zwar abgefragt werden, haben aber den Wert 0 (z.B. sind Fenstergrößen und Farbtiefe erst ab JavaScript 1.2 ermittelbar - der Netscape Navigator 3.0 mit seinem JavaScript 1.1 würde hier also keinen korrekten Wert ermitteln können).

HTML-Code
Externer Quellcode & GIF-Datei: sysvars.zip
Eine fertig in ein HTML-Grundgerüst eingebaute Version gibt es bei MagicHTML.

In den Code integriert sind einige Funktionen die intern genutzt werden, und/oder auch für den sonstigen Gebrauch des Webseiten-Autors zur Verfügung stehen:

  • alertSysVars() (nur im "Developer"-Script) ruft eine Alert-Box auf, die die wichtigsten Informationen in Textform darstellt.
  • lineType(hardware,real) ordnet die Internet-Verbindungsgeschwindigkeit des Browsers (agt_speed) 5 Stufen zu (von "sehr langsam" bis "sehr schnell"), bzw. gibt eine Rückmeldung, ob die Internetverbindung eine bestimmte Geschwindigkeit erreicht (z.B. lineType("DSL"), um schnelle Verbindungen mit mehr Daten zu versorgen ;-)). Ihr können bis zu 2 Parameter übergeben werden, mit denen man den Rückgabewert beeinflussen kann. Wenn die Funktion aufgerufen wird
    1. ohne Parameterübergabe (lineType()) ist das Ergebnis:
      1 (sehr langsame Verbindungsgeschwindigkeit, 1-50 kbps)
      2 (langsame Verbindungsgeschwindigkeit, 50-120 kbps)
      3 (mittlere Verbindungsgeschwindigkeit, 120-300 kbps)
      4 (schnelle Verbindungsgeschwindigkeit, 300-600 kbps)
      5 (sehr schnelle Verbindungsgeschwindigkeit, >600 kbps)
    2. mit "minimalem" Hardwareparameter (lineType("Hardware")) ist das Ergebnis bei
      "Modem": true wenn >0 kbps
      "ISDN" : true wenn >=50 kbps, false wenn <50 kbps
      "Cable": true wenn >=120 kbps, false wenn <120 kbps
      "DSL"  : true wenn >=300 kbps, false wenn <300 kbps
      "High" : true wenn >=600 kbps, false wenn <600 kbps
    3. mit "realem" Hardwareparameter (lineType("Hardware",true)) ist das Ergebnis
      "Modem": true wenn >0 und <50 kbps, false wenn >=50 kbps
      "ISDN" : true wenn >=50 und <120 kbps, false wenn <50 oder >=120 kbps
      "Cable": true wenn >=120 und <300 kbps, false wenn <120 oder >=300 kbps
      "DSL"  : true wenn >=300 und <600 kbps, false wenn <300 oder >=600 kbps
      "High" : true wenn >=600 kbps, false wenn <600 kbps
    Falls die Systemvariable agt_speed -1 (Verbindungsgeschwindigkeit nicht ermittelbar) oder 0 (Verbindungsgeschwindigkeit noch nicht ermittelt) ist, gibt lineType() immer 0 zurück. Wenn man also die wahrscheinliche Internethardware des Anwenders herausfinden möchte, so ginge dies - wie in alertSysVars() - z.B. mit folgendem Code:
    var m=lineType();
    if(m>4) { Modem="Standleitung"; }
    else if(m>3) { Modem="DSL-Modem"; }
    else if(m>2) { Modem="Kabelmodem"; }
    else if(m>1) { Modem="ISDN-Modem"; }
    else if(m>0) { Modem="Analog-Modem";}
    else { Modem="?"; }

    Oder als Einzeiler: var m=lineType(); Modem=((m>4)?"Standleitung" : (m>3)?"DSL-Modem":(m>2)?"Kabelmodem" : (m>1)?"ISDN-Modem" : (m>0)?"Analog-Modem" : "?"); Zu beachten ist dabei natürlich, daß, selbst wenn agt_speed erst nach dem Laden der Seite ermittelt wird, der Anwender ja gleichzeitig andere Fenster oder sonstige Dateien laden könnte. Wie agt_speed selbst, ist auch das darauf aufbauende lineType() keine absolute Angabe, sondern immer nur ein Blick auf die zum Messzeitpunkt existierende Situation ...
  • deFocus(element,always) kann ein Element deaktivieren/defokussieren (z.B. um beim IE den ärgerlichen Rahmen um aktivierte (Image-)Links zu entfernen). Der Funktion können bis zu 2 Parameter übergeben werden:
    1. element ist das zu defokussierende Objekt (also z.B. der Link)
    2. always ist ein Flag, mit dem dafür gesorgt werden kann, daß das Objekt auf jeden Fall (true) defokussiert wird (sofern technisch möglich).
    Dabei ist es empfehlenswert, die Defokussierung an das JavaScript-Ereignis onMouseUp zu koppeln (<a href="seite.htm" onMouseUp="deFocus(this);">Link</a>). Dies hat den Vorteil, daß die Tastatursteuerung (dort ist der Rahmen ja zur Orientierung gedacht und wirklich sinnvoll) möglichst wenig beeinträchtigt wird. Das mit dem IE 5 eingeführte (proprietäre) HTML-Attribut hidefocus (bzw. dem XML-Attribut hidefocus="true") hat die Nachteile, den Rahmen auch bei Tastatursteuerung zu unterdrücken und auf weniger Browsern zu funktionieren - es gibt aber auch eine Möglichkeit der Rahmenunterdrückung via CSS: style="outline:0;" (CSS 3 - wird noch von keinem Browser unterstützt) & style="-moz-outline:0;" (Mozilla-Style - wird von ein paar Browsern unterstützt). Die Verwendung von onClick als "Träger der Defokussierung" hat den Nachteil, daß zumindest der IE den enthaltenen Code auch dann ausführt, wenn der Link nicht mit einem Mausklick, sondern über Tastatur aktiviert wurde. Da bei der Defokussierung nicht nur der gestrichelte Rahmen entfernt wird, sondern auch die aktuelle Position zurückgesetzt wird, würde bei der nächsten Verwendung der Tabulator-Taste (zur Ansteuerung des nächsten Links per Tastatur) nicht der darauf folgende Link ausgewählt, sondern wieder von vorne begonnen. Der Vorteil einer separaten Funktion statt des verbreiteten Direktaufrufs on[...]="this.blur();" liegt in der leichteren Erweiterbarkeit, da die Funktion als externes JavaScript global für alle Seiten einheitlich geändert werden kann. Außerdem ist die Funktion so geschrieben, daß sie auch auf alten Browsern fehlerfrei läuft, die einen Fokus auf einem Link nicht deaktivieren können. Wird gar die Steuerungsvariable do_deFocus an den IE gebunden (Voreinstellung), so wird der Fokus auch nur beim IE deaktiviert und nicht bei Browsern, die (um Grafiklinks) gar keinen störenden Linkrahmen machen. Falls man trotzdem sichergehen will (z.B. für gestylte Textmenüs, wo der Rahmen bei jedem Browser stören würde), so kann man der Funktion zusätzlich true als zweiten Parameter übergeben.
  • ceh() (Critical Error Handler) beinhaltet den Code für den Umgang mit eventuell auftretenden Script-Fehlern.
  • winResize() wird automatisch aufgerufen, wenn sich die Größe des Dokuments/Browserfensters ändert, und aktualisiert dabei die Größenvariablen. Um in diesem Fall eigene Funktionen einzubinden ohne den SysVars-Code selbst zu ändern, wird dabei auch die Funktion magicXL() aufgerufen (der Aufruf ist allerdings auskommentiert: sollen wirklich mit dieser Funktion eigene JavaScript-Befehle ausgeführt werden, so muß vorher die Kommentarkennung // vor dem Aufruf entfernt werden).
  • rc(text,chars,subs,insensitive) (Replace Chars) dient zum Ersetzen von Zeichen in einem String. Dabei wird in text der zu durchsuchende Text übergeben, in chars die zu ersetzenden Zeichen, in subs die Ersatzzeichen, und insensitive bestimmt, ob dabei die Groß-/Kleinschreibung ignoriert wird (true), oder nicht (false). Beispiel: rc("Kleiner Test","e","a") ergibt "Klainar Tast"
  • cc(text,chars) (Count Chars) ermittelt die Häufigkeit von Zeichen in einem String. In text steht dabei der zu durchsuchende Text, in chars die zu suchenden Zeichen). Beispiel: cc("Kleiner Test","e") ergibt 3

Wie bereits erwähnt, benötigen einige dieser Routinen spezielle Steuerungsvariablen, von deren Wert abhängt, wie sich die jeweilige Funktion verhält, bzw. ob sie überhaupt aufgerufen wird. Diese Steuerungsvariablen sind am Ende des SysVars-Codes positioniert, so daß man den eigentlichen Programmcode ggf. leicht durch eine neuere Version ersetzen kann, ohne die persönlichen Einstellungen dieser (und ggf. weiterer) Steuerungsvariablen dabei zu überschreiben. Diese Steuerungsvariablen sind z.Zt.:

  • do_ceh steuert ceh() und sorgt dafür, daß ein möglicher Fehler im Script abgefangen wird (true) oder nicht (false). Voreingestellt ist is_online, d.h. ein möglicher Fehler wird nur abgefangen, wenn die Seite online vom Server geholt wurde, nicht jedoch, wenn er beim Laden von der Festplatte auftritt.
  • do_resize steuert, ob die Funktion winResize() (bei einer Größenänderung) nur die Größenvariablen neu ermittelt (false) oder das Dokument neu lädt (true - Voreinstellung). Das Neuladen ist bei manchen alten Browsern (Netscape Navigator 4.x) notwendig, um Darstellungsfehler zu vermeiden. Aber auch neuere Browser können zu Darstellungsfehlern neigen, insbesondere beim Einsatz von JavaScript zur Seitendarstellung/DHTML (nachträgliche Änderung der Framegrößen, Generierung von HTML-Code in Abhängigkeit von den Abmessungen des Browsers, ...). Bei reinem HTML-Code mit Fließtext kann diese Variable ruhig false sein.

Sinnvollerweise kann man hier natürlich auch weitere Steuerungsvariablen unterbringen und an Systemvariable koppeln. Als Beispiele seien aufgeführt:

  • do_frameset zur Steuerung einer (nicht enthaltenen) Funktion zum Nachladen eines Framesets. Anwendungsbeispiel (für ein externes Script - ausgeführt von einem Inhaltsframe):
    if(!is_frame && do_frameset) { window.location.replace('frameset.htm'); }
    Das Frameset frameset.htm würde dann z.B. nachgeladen bei do_frameset=
    • true (immer)
    • is_online (nur bei Online-Aufruf)
    • is_online && !doc_xServer (bei Online-Aufruf per URL/Bookmark)
    • is_xcall (bei Link von außen, z.B. von einer Suchmaschine)
    • false (nie)
    (natürlich nur, falls das Dokument nicht ohnehin schon innerhalb eines Framesets läuft, was mit !is_frame abgefragt wird). Empfehlenswert ist es, das Nachladen des Framesets an is_xcall zu koppeln! Dann bekommt der Besucher z.B. via Suchmaschine das Frameset zu sehen, aber er kann auf Wunsch die Seite auch ohne Frameset betrachten (z.B. indem er die Seite explizit in ein eigenes Fenster lädt - nun wird das Frameset nicht nachgeladen). Dann sollte dem Anwender allerdings ein Button/Menüpunkt zur Verfügung stehen, über den er das Frameset nachträglich manuell laden kann (diese Seiten sind so konfiguriert). Auch empfiehlt es sich, das Frameset ggf. sofort nachzuladen und nicht erst nachdem die Seite fertiggeladen wurde (also Aufruf vor dem BODY-Tag und nicht erst am Ende der Seite, bzw. gar mittels onLoad).
  • do_deFrame zur Steuerung einer (nicht enthaltenen) Funktion, um ein fremdes, unerwünschtes Frameset zu entfernen. Anwendungsbeispiel (für ein externes Script - ausgeführt vom eigenen Frameset oder einer alleinstehenden Seite):
    if(is_frame && do_deFrame) { top.location.replace(self.location.href); }
    Das fremde Frameset würde dann z.B. entfernt bei do_deFrame=
    • true (immer)
    • is_online (nur bei Online-Aufruf)
    • is_xcall (wenn das Frameset auf einem fremden Server liegt)
    • false (nie)
  • do_uncache zur Steuerung einer (nicht enthaltenen) Funktion zum Nachladen der Original-Seite. Anwendungsbeispiel (für ein externes Script):
    if(is_cached && do_uncache) { top.location.replace()=doc_CachedURL; }
    Falls das Script von einer Seite im Google-Cache aufgerufen wurde, so enthält doc_cachedURL den URL der Original-Seite. Man könnte so die gecachte Version "überladen", und dem Suchenden stets die aktuelle Seite präsentieren (allerdings mit Bedacht nutzen, da Google ja auch die gefundenen Stellen in der Seite markiert).
  • do_blending dient zur Steuerung der (nicht enthaltenen) Funktion PageBlending, mit der man (auf dem IE - möglichst erst ab Version 6) HTML-Seiten ineinander überblenden kann (Anwendungsbeispiele siehe dort).

Anmerkungen: Damit is_w3cxDOM korrekt besetzt werden kann, muß (pflichtgemäß) das TITLE-Tag vorhanden sein - und zwar vor dem SCRIPT-Tag, das SysVars beinhaltet! Das "erweiterte W3C-DOM" kennt zusätzlich zum Standard-W3C-DOM die Funktion getElementsByTagName (übernommen aus dem W3C-XML-DOM) sowie die (äußerst praktische) Eigenschaft innerHTML (übernommen aus dem IE-DOM). Faktisch unterstützen alle neueren Browser (IE ab 5, Navigator ab 6, Opera ab 7, Mozilla, Konqueror/Safari) nicht nur das Standard-, sondern auch das "erweiterte W3C-DOM" (bei Opera kennzeichnet SysVars erst ab Version 7 DOM als vorhanden, da ältere Opera-Versionen die Standard-W3C- und IE-DOMs ärgerlicherweise nur völlig unzulänglich unterstützen - um diese Unverschämtheit mal vorsichtig zu umschreiben ...).

Beim FTP-Zugriff können dem Server Username und Passwort vorangestellt werden ("ftp://username:passwort@ftp.example.com"). Manchmal wird diese Schreibweise (unerlaubterweise) auch bei HTTP verwendet (für HTTP-Authentifizierung). Entsprechend werden dann die Variablen doc_User & doc_Password belegt. Einige Provider haben diese Schreibwesie eine zeitlang auch für per JavaScript angesteuerte Pseudo-Subdomains (sog. "@Domains") benutzt.
Da der IE hierbei jedoch ein mal wieder ein Sicherheitsproblem hatte, funktioniert diese Methode nicht mehr im Internet Explorer ab IE 6 Service Pack 2. Unfähig wie MS ist, haben sie lieber diese Möglichkeit komplett unterbunden, anstatt nur das Problem zu beheben. Um diese Art der Zugangsdaten-Übergabe mit dem IE trotzdem nutzen zu können, kann man sie allerdings mittels Registry-Eintrag auch wieder freischalten.

Die Variable doc_Referrer entspricht der JavaScript-Eigenschaft document.referrer, ist aber im Offline-Betrieb immer leer, während document.referrer von den verschiedenen Browsern im Offline-Betrieb unterschiedlich gehandhabt wird. Aber auch wenn der Referrer einen unsinnigen Wert enthält, weil in ihm kein Server enthalten ist (z.B. Aufruf aus den Bookmarks oder via einem "Localhost-Server"), oder weil er vom Surfer verschleiert wird, ist doc_Referrer leer, ebenso wie die doc_x-Variablen (is_icall ist dann immer sicherheitshalber (um ggf. Endlosschleifen zu vermeiden) true und is_xcall immer false).

Die Variable doc_Search entspricht der JavaScript-Eigenschaft location.search, jedoch ohne dem "?".

Können Größenvariablen (agt_width, etc.) nicht ermittelt werden, dann ist ihr Wert 0. Da der IE beim Ladebeginn nicht alle Größenvariablen setzen kann, muß nach dem Laden des BODY-Tags SysVarsBody() aufgerufen werden. Außerdem gibt es beim IE keine passenden Größenangaben für das Browserfenster (agt_width & agt_height) - es wird in diesem Fall versucht, "ungefähre" Werte zu ermitteln.

Die Variablen für Verzeichnis- & Dateinamen liefern zumindest im Offline-Betrieb (also beim Laden von Festplatte) unterschiedliche Ergebnisse, je nach Betriebssystem/Browser (lange Namen mit Klein-/Großschreibung: z.B. Windows 9x, kurze Namen mit Großschreibung, z.B. Windows 3.x). Es empfiehlt sich also, dies bei Abfragen zu beachten und die Namen ggf. in ein einheitliches Format zu transferieren (mit toLowerCase() und dann nur die ersten 6 Buchstaben beachten). Aber wer entwickelt schon noch mit Windows 3.x (und online spielt es ohnehin keine Rolle) ... =;-)

Die Geschwindigkeitsermittlung der Internetverbindung (agt_speed) variiert ein wenig von Browser zu Browser, ist also nur ein Näherungswert - schon weil, mit Rücksicht auf langsame Analog-Modems, die Testdatei nur 50 KByte groß ist (sie heißt sysvars.gif, muß im Root-Verzeichnis der Website liegen und wird nicht gecached). Um agt_speed mit einem sinnvollen Wert zu belegen (bei schnellen Internetverbindungen wird ein relativ zu niedriger Wert ermittelt, da die geringe Dateigröße dann in keinem Verhältnis mehr zum "HTTP-Overhead" steht - also dem Aufwand, der ja bei jedem Server-Zugriff anfällt), muß die Routine SysVarSpeed() aufgerufen werden - am Besten nach dem Laden der HTML-Seite, also mit onLoad, damit der Wert möglichst nicht vom Ladevorgang anderer Seitenelemente beeinträchtigt wird Wird SysVarSpeed() nicht aufgerufen, so hat agt_speed den Wert 0. Konnte die Geschwindigkeit nicht ermittelt werden (weil der Browser zu alt ist, oder weil sysvars.gif nicht gefunden wurde), dann ist ihr Wert -1 (diesen Wert hat die Variable auch während der Testzeit selbst!). Um also den Wert nur einmalig zu ermitteln, klammert man den Aufruf möglichst mit einer Abfrage von agt_speed:

if(!agt_speed){SysVarSpeed();}

Anschließend sollte man den Wert an die nächste Seite übergeben, damit es nicht zu unnötigen Mehrfachermittlungen kommt. Die Übergabe kann z.B. über den Namen des Fensters erfolgen (einfache Variante: top.name=agt_speed), was nur im Netscape Navigator 2.x nicht funktioniert (wenn das Ganze nicht ohnehin in einem externen Script geschieht - diese werden im Navigator 2.x nicht ausgeführt -, sollte ggf. eine vorherige Abfrage mit is_nav2 erfolgen). Auf der nächsten Seite kann man den Wert dann dort wieder auslesen (einfache Variante: agt_speed=parseInt(top.name); agt_speed=(agt_speed)?agt_speed:0;). Da dies nicht ganz trivial ist, sollte man sich also schon ein wenig mit JavaScript auskennen, falls man diese Möglichkeit nutzen möchte. ;-)

Achtung: Es ist gut zu wissen, auf welchem Browser die Seite angezeigt wird, um ggf. auf spezielle Browser-Fehler oder -Eigenschaften eingehen zu können (so wird dieser Frame/dieses "GEM-Fenster" z.B. nur im IE mit einem CSS-Rand versehen, da die anderen Browser diesen Rand nicht außerhalb, sondern innerhalb des Frames darstellen). Aber auf die Browsererkennung kann man sich nie zu 100% verlassen! Die in diesem Script verwendete Erkennung ist allerdings die mit Abstand sicherste, die es z.Zt. wohl gibt. Dringend Abstand nehmen sollte man aber prinzipiell von Browserweichen, die nur mit navigator.userAgent oder document.all arbeiten (ersteres ist beliebig manipulierbar - in den meisten Nicht-IEs sogar einfach per Mausklick -, letzteres nur ein Hinweis darauf, daß der Browser das IE-DOM unterstützt, was aber, außer dem IE selbst natürlich, eben noch einige andere Browser tun! Der JavaScript-Programmierer sollte sich also prinzipiell nicht an der Browser-Version orientieren, wenn er bestimmte Funktionen und Eigenschaften von JavaScript (bzw. dem DOM) nutzen möchte, zumal auch ein (scheinbar) gleicher Browser in gleicher Version auf gleichem System durchaus unterschiedliche Funktionen & Eigenschaften unterstützen kann. Dies fing schon mit dem ersten JavaScript-Browser, dem Netscape Navigator 2.0, an, der in der Unix-Version die Funktion Math.random unterstützte, in der Windows-Version jedoch nicht. Es setzte sich fort bis zu Microsofts Internet Explorer, wo für das Objekt window das proprietäre Unterobjekt external eingeführt wurde, über das u.a. mit AddFavorite ein Lesezeichen gesetzt werden kann - in der AOL-Version dieses Browsers fehlt jedoch, trotz gleicher Versionsnummer & Betriebssystem, external, und Mozillas kennen external mittlerweile auch, aber eher zu internen Zwecken und ohne AddFavorite. Es gilt also: Stets auf das Vorhandensein der konkreten Funktion oder Eigenschaft abfragen, bzw. die Systemvariablen nutzen, die dies schon getan haben. Eine solche Abfrage wird durch eine spezielle Eigenschaft von JavaScript gefördert: Während der (ungeschützte) Aufruf einer Funktion oder Eigenschaft bei unzureichender JavaScript-Version einen Fehler produziert, wird der gleiche Aufruf in einer if-Abfrage als true (vorhanden) oder false (nicht vorhanden) interpretiert! Um also eine bestimmte Eigenschaft zu nutzen, fragt man erst ab, ob die Funktion existiert, dann ob Eigenschaft existiert und führt erst dann die Eigenschaft aus. Mit UND (&&) verbunden, bricht JavaScript beim ersten false ab und führt den folgenden (möglicherweise unzulässigen Code) erst gar nicht aus. Abstrahiertes Beispiel:

if(Funktion && Funktion.Eigenschaft) { Funktion.Eigenschaft=Wert; }

Zwar macht diese Vorgehensweise eine klassische Browserweiche in den meisten Fällen überflüssig, leider funktioniert sie aber nicht mit Programm-Konstrukten/Befehlen, und leider auch nicht bei allen Funktionen (da hilft nur, auf alten Browsern zu testen, oder wenigstens hilfsweise agt_jsVersion zu nutzen). Wer also z.B. switch/case einsetzen möchte, der bekommt auf JavaScript-1.0-Browsern eine Fehlermeldung, selbst wenn die betreffende Stelle eigentlich gar nicht ausgeführt wird - man muß diesen Programmteil ausgliedern und explizit mit der entsprechenden JavaScript-Version kennzeichnen (und darauf achten, daß JavaScript-1.0-Browsern nicht "ins Leere" springen, wenn sie zur betreffenden Stelle gelangen). Leider wird die Angabe der JavaScript-Version im SCRIPT-Tag mit z.B. language="JavaScript1.5" jedoch von älteren Browsern ignoriert (oder fehlinterpretiert), und beim neuen Attribut type="text/javascript" agieren selbst neuere Browser recht "eigenwillig". Am besten also, man schreibt JavaScript ab Version 1.1 in eine externe Datei (die von 1.0-Browsern ohnehin nicht ausgeführt wird), umklammert neuere Befehle so, daß sie nicht von unpassenden Browsern angesprungen werden, und hofft ...

Testen Sie ihre Seiten sicherheitshalber also immer auch mal mit umbenannten externen JavaScript-Dateien, um zu sehen, wie ihre Seiten reagieren, wenn das externe JavaScript nicht geladen werden kann!


Updates:
28.12.2007: 
Aktualisierung. Es wird jetzt JavaScript bis Version 1.8 inkl. (Mozilla 3) erkannt.
26.11.2007: 
Erweiterungen. Hinzugekommen ist is_oldop für Operas ohne vollständige DOM-Unterstützung (Opera<=8.x) und is_ieSafer für IEs ab Version 6 mit Service Pack 2. Verbessert wurde die Browsererkennung, und es wird jetzt JavaScript bis Version 1.7 inkl. (Mozilla 2) erkannt.
03.01.2004: 
Erweiterungen. Hinzugekommen ist die Unterroutine lineType(), und alertSysVars() wurde ein wenig verändert (der wahrscheinliche Typ der Internetverbindung wird ermittelt, und bei Browsern die sich "tarnen", werden jetzt auch die Versionsnummern der "Tarnbrowser" ausgegeben).
06.12.2003: 
Korrektur & Erweiterungen. Korrigiert wurde die Ermittlung des IE (die AOL-Version des IE wurde wegen anderer Eigenschaften nicht als solcher erkannt). Neu hinzugekommen ist die Erkennung des Mac-Browsers Safari (is_saf & agt_safVersion).
29.11.2003: 
Änderungen & Erweiterungen. Die Variable agt_time wurde umbenannt in doc_time. Neu hinzugekommen ist die Ermittlung der Verbindungsgeschwindigkeit (agt_speed).
22.11.2003: 
Korrekturen & Erweiterungen. Bugfixes bei Behandlung der Default-Datei (doc_File) und der Pfadtiefe (doc_PathDeep). Hinzugekommen ist der Pfad zur Root-Ebene (doc_rootPath).
08.11.2003: 
Korrekturen. Korrigiert wurde die Behandlung des IE 3.0 (Workarounds).
01.11.2003: 
Korrekturen & Erweiterungen. Korrigiert wurde die Versionsermittlung von Opera, sowie Navigator-2-Behandlung (Workarounds). Hinzugekommen ist die Nummer der verwendeten JavaScript-Version (agt_jsVersion).
18.10.2003: 
Korrekturen & Erweiterungen. Korrigiert wurden die Größenermittlung (jetzt mit Erneuerung des Browser-Bildschirms nach einer Änderung) und die Server-/Dateinamen-Auswertung (jetzt mit doc_User & doc_Password). Außerdem neu: doc_fullFile
03.10.2003: 
Komplett neue Version mit deutlich mehr Variablen!


Kurz-URL dieses Artikels: http://Coding.binon.net/SysVar