Coding-Schatzkästlein
| |||||||||||||||||||||||||||||||||||||||||||||||||||
| 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- | |||
| 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 (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:
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 übergebendefaultFile 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-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:
String):
Number):
SysVarSpeed())SysVarsBody())SysVarsBody())SysVarsBody())SysVarsBody())Boolean: true oder false):
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-
Boolean: true oder false):
String):
Number):
SysVarsBody())SysVarsBody())Boolean: true oder false):
Boolean: true oder false):
Die verwendeten Sprachen sind verschiedene JavaScript-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- |
|---|
In den Code integriert sind einige Funktionen die intern genutzt werden, und/oder
auch für den sonstigen Gebrauch des Webseiten-
alertSysVars()
(nur im "Developer"-Script) ruft eine Alert-lineType(hardware,real) ordnet die Internet-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 wirdlineType()) ist das Ergebnis:1 (sehr langsame Verbindungsgeschwindigkeit, 1-2 (langsame Verbindungsgeschwindigkeit, 50-120 kbps)3 (mittlere Verbindungsgeschwindigkeit, 120-300 kbps)4 (schnelle Verbindungsgeschwindigkeit, 300-600 kbps)5 (sehr schnelle Verbindungsgeschwindigkeit, >600 kbps)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 kbpslineType("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 kbpsagt_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="?"; }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-)element ist das zu defokussierende Objekt (also z.B. der Link)always ist ein Flag, mit dem dafür gesorgt werden kann, daß das
Objekt auf jeden Fall (true) defokussiert wird (sofern technisch möglich).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-hidefocus (bzw. dem XML-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-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-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-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-magicXL() aufgerufen (der
Aufruf ist allerdings auskommentiert: sollen wirklich mit dieser Funktion eigene
JavaScript-// 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-
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-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'); }frameset.htm würde dann z.B. nachgeladen bei do_frameset=true (immer)is_online (nur bei Online-is_online && !doc_xServer (bei Online-is_xcall (bei Link von außen, z.B. von einer Suchmaschine)false (nie)!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-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); }do_deFrame=true (immer)is_online (nur bei Online-is_xcall (wenn das Frameset auf einem fremden Server liegt)false (nie)do_uncache zur Steuerung einer (nicht enthaltenen) Funktion zum
Nachladen der Original-if(is_cached && do_uncache) { top.location.replace()=doc_CachedURL; }doc_cachedURL den URL der Original-do_blending dient zur Steuerung der (nicht enthaltenen) Funktion
PageBlending, mit
der man (auf dem IE - möglichst erst ab Version 6) HTML-
Anmerkungen: Damit is_w3cxDOM korrekt besetzt werden kann,
muß (pflichtgemäß) das TITLE-SysVars beinhaltet! Das "erweiterte
W3C-getElementsByTagName (übernommen aus dem W3C-innerHTML (übernommen
aus dem IE-SysVars
erst ab Version 7 DOM als vorhanden, da ältere Opera-Versionen
die Standard-
Beim FTP-doc_User & doc_Password
belegt. Einige Provider haben diese Schreibwesie eine zeitlang auch für
per JavaScript angesteuerte Pseudo-
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-
Die Variable doc_Referrer entspricht der JavaScript-document.referrer, ist aber im Offline-Betrieb immer leer, während
document.referrer von den verschiedenen Browsern im Offline-doc_Referrer leer, ebenso wie die doc_x-is_icall ist dann immer sicherheitshalber (um ggf. Endlosschleifen zu
vermeiden) true und is_xcall immer false).
Die Variable doc_Search entspricht der JavaScript-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-SysVarsBody() aufgerufen werdenagt_width & agt_height)
- es wird in diesem Fall versucht, "ungefähre" Werte zu ermitteln.
Die Variablen für Verzeichnis- & Dateinamen liefern zumindest im
Offline-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-sysvars.gif, muß im Root-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-SysVarSpeed() aufgerufen werden - am
Besten nach dem Laden der HTML-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. ;-)
navigator.userAgent
oder document.all arbeiten (ersteres ist beliebig manipulierbar -
in den meisten Nicht-Math.random
unterstützte, in der Windows-window das
proprietäre Unterobjekt external eingeführt wurde, über
das u.a. mit AddFavorite ein Lesezeichen gesetzt werden kann - in der
AOL-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-if-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-agt_jsVersion zu nutzen). Wer also z.B. switch/case
einsetzen möchte, der bekommt auf JavaScript-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-
Testen Sie ihre Seiten sicherheitshalber also immer auch mal mit
umbenannten externen JavaScript-
|
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-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-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-doc_File) und der Pfadtiefe (doc_PathDeep). Hinzugekommen
ist der Pfad zur Root-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-agt_jsVersion).
|
|
18.10.2003: |
Korrekturen & Erweiterungen. Korrigiert wurden die
Größenermittlung (jetzt mit Erneuerung des Browser-doc_User & doc_Password). Außerdem neu:
doc_fullFile
|
|
03.10.2003: |
Komplett neue Version mit deutlich mehr Variablen!
|