|
|
|
4.7 JavaScript-Know-How
|
|
|
|
|
4.7.1
Einführung
Das Kapitel "JavaScript-Know-How" ist auf gewisse Weise hybrid: es wird kompliziertes Background-Wissen zusammen mit einfacheren Anwendungsbeispielen dargestellt. Wir beginnen mit dem Thema "Objektorientierte Programmierung", die auch in JavaScript sehr gut funktioniert. Es folgen diverse Beispiel-Scripts zu eng umrissenen Themen: wie überprüft man Formular-Eingaben auf Korrektheit? Wie öffnet man ein neues Fenster? Wie funktioniert eine Browserweiche?
Sehen Sie sich auch die Kommentare direkt im Code an - oft stehen dort Informationen, die im Fließtext selbst nicht mehr gesondert erwähnt werden.
|
|
|
4.7.2
Voraussetzungen
Um die Scripts zu verstehen, müssen Sie JavaScript beherrschen. Wer die Beispiele ausprobieren will, braucht HTML-Editor und einen aktuellen Browser.
|
|
|
4.7.3
Objektorientierte Programmierung
JavaScript ist eine objektorientierte Programmiersprache. Doch wie kann man in JavaScript eigentlich eigene Objektklassen definieren? Bevor Sie sich mit diesem Thema beschäftigen, sollten Sie zumindest grundlegende Kenntnisse über die OOP-Terminologie haben. Sollte das noch nicht der Fall sein, dann finden Sie im Kapitel "JavaScript-Tutorial" einige Erklärungen.
4.7.3.1 Klassen definieren
Der folgende Code zeigt die Erzeugung einer Klasse und die Instanzierung eines Objekts basierend auf der erstellten Klasse:
var instanz_objekt = new meinObject(14);
document.write(instanz_objekt.Eigenschaft);
function meinObject (variable1)
{
this.Eigenschaft = variable1;
}
Wie Sie sehen, reicht also der Aufruf einer einfachen Funktion, verbunden mit dem Schlüsselwort new, um ein Objekt zu erzeugen. Die Funktion enthält dabei die Klassendefinition.
4.7.3.2 Eigenschaften mit this
Um der Klasse Elemente hinzuzufügen, verwenden Sie innerhalb des Konstruktors (so nennt man die Funktion, die für die Konstruktion des Objekts zuständig ist - in diesem Fall ist es meinObject) das Objekt this. Wenn Sie also wie im Beispiel this.Eigenschaft = variable1; schreiben, wird dabei die Objekteigenschaft Eigenschaft erzeugt.
4.7.3.3 Methoden
Methoden sind Funktionen, die zu einem Objekt gehören. Folgender Code zeigt ein Beispiel:
var instanz_objekt = new meinObject();
document.write(instanz_objekt.funk(12));
function meinObject ()
{
this.funk = doIt;
}
function doIt (zahl)
{
return "Zahl: "+zahl*2;
}
Wieder wird also this verwendet, um eine Funktion zu definieren. Dabei gilt das Schema this.NameDerMethode = EntsprechendeFunktion.
4.7.3.4 Eigenschaftsverändernde Methoden
Wenn Sie innerhalb einer Methode eine Eigenschaft ändern wollen, geht das so wie in der Funktion setEigenschaft gezeigt:
var instanz_objekt = new meinObject(14);
document.write(instanz_objekt.Eigenschaft);
document.write("<br>");
instanz_objekt.setEigenschaft();
document.write(instanz_objekt.Eigenschaft);
function meinObject (variable1)
{
this.Eigenschaft = variable1;
this.setEigenschaft = setEigenschaft;
}
function setEigenschaft ()
{
this.Eigenschaft = 12;
}
4.7.3.5 Datenkapselung
Es ist in JavaScript nicht möglich, Daten wirklich zu kapseln, also den Zugriff von außen zu verhindern. Es ist aber trotzdem guter Stil, Zugriffe auf Eigenschaften über Funktionen abzuwickeln. Wir haben das letzte Beispiel etwas erweitert, um das zu demonstrieren:
var instanz_objekt = new meinObject(14);
document.write(instanz_objekt.getEigenschaft());
document.write("<br>");
instanz_objekt.setEigenschaft(12);
document.write(instanz_objekt.getEigenschaft());
function meinObject (variable1)
{
this.Eigenschaft = variable1;
this.setEigenschaft = setEigenschaft;
this.getEigenschaft = getEigenschaft;
}
function setEigenschaft (value)
{
this.Eigenschaft = value;
}
function getEigenschaft ()
{
return this.Eigenschaft;
}
|
|
|
4.7.4
Pop-Ups
Pop-Ups sind grundsätzlich kritisch: viele Benutzer fühlen sich durch sie belästigt. Das nicht zuletzt deswegen, weil die Werbeindustrie das Pop-Up entdeckt hat - Seiten, auf denen man zuerst einmal von einem schönen, blinkenden (nervenden?) Werbe-Pop-Up begrüßt wird, sind Alltag.
Man mag dazu stehen, wie man will - wir beschränken uns hier auf den technischen Aspekt.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/transitional.dtd">
<html>
<head>
<title>Meine erste Test-Seite</title>
<script language="JavaScript1.5" type="text/javascript">
var my_window;
function newWindow()
{
my_window = window.open (
"",
"MeinFenster", // Name des neuen Fensters
+"toolbar=0" // Toobar anzeigen?
+",location=0" // Adresse-Leiste anzeigen?
+",directories=0" // Div. Zusatzleisten anzeigen?
+",status=0" // Statusleiste anzeigen?
+",menubar=0" // Menüleiste anzeigen?
+",scrollbars=0" // Scrollbars anzeigen?
+",resizable=0" // Größe des Fensters veränderbar?
// Wenn Breite und Höhe des Fensters
// festgelegt werden sollen, dann müssen
// die beiden nächsten Zeilen durch
// Entfernen der beiden Slashes am Anfang
// aktiviert werden.
// Die Zahlen hinter dem Gleichzeichen
// geben die zu setzenden Werte an.
+",width=100" // Breite in Pixeln
+",height=500" // Breite in Pixeln
);
// Wenn die Position des neuen Fensters verändert
// werden soll, verwenden Sie die folgende
// Zeile.
my_window.moveTo(
100, // X-Koordinate
200 // Y-Koordinate
);
// Hier die URL des neuen Fensters eingeben
my_window.location.href = "http://www.aboutwebdesign.de";
}
</script>
</head>
<body>
<div onClick="newWindow();">Neues Fenster öffnen!</div>
</body>
</html>

Das Script verwendet die open-Methode des Hauptfensters. Um hinterher noch die Position ändern zu können, müssen wir das Setzen der URL auf einen späteren Zeitpunkt verschieben.
|
|
|
4.7.5
Formulareingaben überprüfen
Eines der Haupteinsatzgebiete von JavaScript ist es, Formulareingaben auf ihre Plausibilität zu prüfen. Obwohl bewusste Fehleingaben damit natürlich nicht verhindert werden können, ist es so doch möglich, wenigstens für syntaktische Korrektheit zu sorgen.
Bitte beachten Sie: JavaScript-Überprüfungen können und dürfen serverseitige Datenüberprüfungen nicht ersetzen. Es ist immer möglich, HTML-Formulare und damit auch JavaScript durch direkte Server-Anfragen zu umgehen.
Das folgende Script überprüft ein Beispiel-Formular auf Korrektheit. Besonders interessant dabei sind die Überprüfung von Radio- und Check-Buttons, Auswahllisten sowie die Mustererkennung. Für letztere verwenden wir die regulären Ausdrücke von JavaScript, was einen Browser der 4er-Generation voraussetzt.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/transitional.dtd">
<html>
<head>
<title>Meine erste Test-Seite</title>
<script language="JavaScript1.5" type="text/javascript">
function CheckData()
{
var fail = 0;
// Ist ein Feld überhaupt gesetzt?
if (document.Daten.Name.value == "")
{
alert("Bitte einen Namen eingeben!");
fail = 1;
}
// Sind die Eingaben eines Feldes lang genug?
if (document.Daten.Name.value.length < 5)
{
alert("So kurze Namen gibt es nicht! Bitte Eingabe im Namensfeld korrigieren!");
fail = 1;
}
// Simpler Check auf bestimmte Eingabe
if (!((document.Daten.Geschlecht.value == "M") || (document.Daten.Geschlecht.value == "W")))
{
alert("Bitte bei Geschlecht nur ein M oder ein W eingeben!");
fail = 1;
}
// Kommt ein Zeichen in einem Feld vor?
if (document.Daten.Email.value.indexOf('@') == -1)
{
alert("Bitte eine gültige Email-Adresse eingeben - das @ fehlt!");
fail = 1;
}
// Liegt ein gültiges Datum vor? Reguläre Ausdrücke kommen zum Einsatz!
if (document.Daten.Geburt.value.search(/^(\d\d)\.(\d\d)\.(\d\d\d\d)$/) == -1)
{
alert("Bitte ein Datum im angegebenen Format eingeben!");
fail = 1;
}
else
{
var reg = /^(\d\d)\.(\d\d)\.(\d\d\d\d)$/;
reg.exec(document.Daten.Geburt.value);
if ((RegExp.$1 < 0) || (RegExp.$1 > 31))
{
alert("Bitte einen Tag zwischen 1 und 32 angeben!");
fail = 1;
}
if ((RegExp.$2 < 0) || (RegExp.$2 > 12))
{
alert("Bitte einen Monat zwischen 1 und 12 angeben!");
fail = 1;
}
if ((RegExp.$3 < 1900) || (RegExp.$2 > 2001))
{
alert("Bitte ein Jahr zwischen 1900 und 2001 angeben!");
fail = 1;
}
}
// Auf Radiobuttons/Checkboxen zugreifen..
for (var i = 0; i < document.Daten.Wunsch.length; i++)
{
var here_checked = document.Daten.Wunsch[i].checked;
var here_val = document.Daten.Wunsch[i].value;
if (here_checked)
{
// Irgendwas mit dieser Erkenntnis machen...
alert ("Nummer "+i+" mit dem Wert "+here_val+" wurde ausgewählt");
}
}
// Auf Listboxen zugreifen
var selected = document.Daten.Bundesland.options.selectedIndex; // Index des gewählten Elements
var here_value = document.Daten.Bundesland.options[selected].value; // interner Wert des gewählten Elements
var here_name = document.Daten.Bundesland.options[selected].text; // angezeigter Bezeichner des g. Elements.
if (fail == 1)
{
return false;
}
else
{
return true;
}
}
</script>
</head>
<body>
<form action="xyz.cgi" method="post" name="Daten" id="Daten" onSubmit="return CheckData();">
Name: <input type="text" name="Name"><br>
Geschlecht (M/W): <input type="text" name="Geschlecht"><br>
Email-Adresse: <input type="text" name="Email"><br>
Geburtstag (TT.MM.JJJJ): <input type="text" name="Geburt"><br>
<input type="radio" name="Wunsch" value="ja"> Newsletter bestellten
<input type="radio" name="Wunsch" value="nein"> Newsletter nicht bestellen
<bR>
Bundesland (nur zwei): <select name="Bundesland">
<option value="1" SELECTED>NRW</option>
<option value="2">Bayern</option>
</select>
<input type="submit" value="Abschicken!">
</form>
</body>
</html>

Grundsätzlich verwendet man also document.Formularname.Elementname, um auf ein Element zuzugreifen. Bei Radiobuttons und Checkboxen ist Elementname ein Array, muss also über eine Schleife abgefragt werden. Listboxen müssen etwas anderes angesprochen werden: document.Formularname.Elementname.options. Wie das im Detail geht, das zeigt der Code.
|
|
|
4.7.6
Browserweiche
Wer verschiedene Layouts für verschiedene Browser programmiert, der will eine komfortable Möglichkeit haben, zur jeweils passenden Version weiterzuleiten. Die folgende Browserweiche hilft dabei - sie fragt Browser, Browserversion, Bildschirmauflösung, Java-Unterstützung und Flash-Unterstützung ab. Am Ende des Scripts stehen einige Beispiel-Abfragen, die je nach Verwendungszweck erweitert werden müssen.
<script language= "JavaScript">
// Browser
ie = ((document.all) && (window.offscreenBuffering)) ? true : false;
nn = ((document.captureEvents) && (!document.getElementById)) ? true : false;
mz = ((document.getElementById) && (!document.all) && (document.documentElement)) ? true : false;
op = ((document.getElementById) && (navigator.userAgent.indexOf('Opera') != -1)) ? true : false
// Browser-Version
b_version = navigator.appVersion.substring(0,1);
// Bildschirm-Auflösung
r_small = (screen.width < 640) ? true : false; // Kleiner Bildschirm
r_640 = (screen.width >= 640) ? true : false; // Mindestens 640x480
r_800 = (screen.width >= 800) ? true : false; // Mindestens 800x600
r_1024 = (screen.width >= 1024) ? true : false; // Mindestens 1024x768
r_1280 = (screen.width >= 1280) ? true : false; // Mindestens 1280x1024
r_1600 = (screen.width >= 1600) ? true : false; // Mindestens 1600x1200
// Java?
javaok = (navigator.javaEnabled()) ? true : false;
// Abfragen
// z.B.: Weiterleitung zu einer Seite
if (ie && r_1280 && javaok && (b_version >= 4))
{
// IE, Auflösung größer als 1280x1024, Java an, Browserversion >= 4
document.location.href="xxyt.html";
}
if ((ie || nn) && r_800 && (b_version >= 3))
{
// IE oder NN, Auflösung größer als 800x600, Java wird nicht gecheckt, Browserversion >= 3
document.location.href="xxyt.html";
}
if (!(ie) && !(b_version >= 3))
{
// Kein IE und gleichzeitig Browserversion < 3
document.location.href="xxyt.html";
}
</script>
Es ist sinnvoll, hier noch einen <noscript>-Bereich einzubauen. Dort könnte der Anwender z.B. gebeten werden, manuell seine Systemkonfiguration auszuwählen. Gut ist dieser Ansatz jedoch nicht - viele Anwender wissen gar nicht, welche Bildschirmauflösung sie haben. Wir schlagen daher vor, bei ausgeschaltetem JavaScript Anwender auf eine Seite weiterzuleiten, die so kompatibel wie möglich ist - also optimiert auf 800x600, ohne Flash und ohne Java.
Flash ist in dieser Browserweiche noch nicht eingebaut. Es gibt zwar Möglichkeiten, auf Flash mit JavaScript zu prüfen. Das ist aus verschiedenen Gründen nicht gerade optimal: Auf vielen Systemen funktioniert diese Methode überhaupt nicht.
Ein anderer Ansatz - mit SSI - ist folgender: in die Startdatei wird eine kleine Flash-Datei eingebunden, die so schnell wie möglich zur auf Flash optimierten Version weiterleitet. Soll heißen: es wird nur dann weitergeleitet, wenn Flash funktioniert. Im HTML-Code wird ebenfalls eine Weiterleitung eingestellt, allerdings eine, die erst nach 10 Sekunden wirksam wird. Wenn Flash also aktiviert ist, dann wird die Weiterleitung innerhalb des Flash-Films aktiv. Wenn nicht, dann die HTML-Weiterleitung.
Zunächst sollten Sie sich also um den Flash-Film kümmern, der weiterleitet. Gute Artikel dazu gibt es von <a href="http://www.macromedia.com/home/searchresults/?sp-k=&sp-p=any&sp-a=00050d14-sp00000001&sp-q=flash+detection">Macromedia</a> oder auch von <a href="http://www.flashworker.de/tutorial/76/001.html">Flashworker.de</a>.
Irgendwo müssen Sie also innerhalb Ihres Weiterleitungs-Films eine Weiterleitungs-URL eingeben. Setzen Sie hier die URL weiche.shtml?flashok ein. Vorausgesetzt, die die Weiche enthaltende Datei heißt auch weiche.shtml, könnte der Code dann so aussehen. Ganz unten muss allerdings noch der passende Flash-Film mit Browserweiche eingebunden werden.
<html>
<head>
<META HTTP-EQUIV="Refresh" CONTENT="10;URL=weiche.shtml?noflash">
<script language= "JavaScript">
// Browser
ie = ((document.all) && (window.offscreenBuffering)) ? true : false;
nn = ((document.captureEvents) && (!document.getElementById)) ? true : false;
mz = ((document.getElementById) && (!document.all) && (document.documentElement)) ? true : false;
op = ((document.getElementById) && (navigator.userAgent.indexOf('Opera') != -1)) ? true : false
// Browser-Version
b_version = navigator.appVersion.substring(0,1);
// Bildschirm-Auflösung
r_small = (screen.width < 640) ? true : false; // Kleiner Bildschirm
r_640 = (screen.width >= 640) ? true : false; // Mindestens 640x480
r_800 = (screen.width >= 800) ? true : false; // Mindestens 800x600
r_1024 = (screen.width >= 1024) ? true : false; // Mindestens 1024x768
r_1280 = (screen.width >= 1280) ? true : false; // Mindestens 1280x1024
r_1600 = (screen.width >= 1600) ? true : false; // Mindestens 1600x1200
// Java?
javaok = (navigator.javaEnabled()) ? true : false;
// Flash
flash = false;
<!--#if expr="${QUERY_STRING} = 'flashok'" -->
flash = true;
<!--#endif -->
// Abfragen
// z.B.: Weiterleitung zu einer Seite
<!--#if expr="${QUERY_STRING} != ''" -->
if (ie && r_1280 && javaok && (b_version >= 4) && flash)
{
// IE, Auflösung größer als 1280x1024, Java an, Browserversion >= 4, Flash an
document.location.href="xxyt.html";
}
if ((ie || nn) && r_800 && (b_version >= 3) && !(flash))
{
// IE oder NN, Auflösung größer als 800x600, Java wird nicht gecheckt, Browserversion >= 3, kein Flash
document.location.href="xxyt.html";
}
if ((!ie) && r_800 && (b_version >= 3))
{
// IE oder NN, Auflösung größer als 800x600, Java wird nicht gecheckt, Browserversion >= 3, Flash wird nicht gecheckt
document.location.href="xxyt.html";
}
<!--#endif -->
</script>
</head>
<body>
<!--#if expr="${QUERY_STRING} = ''" -->
<!-- Hier Flash-Film einbinden! -->
<!--#endif -->
</body>
</html>
|
|
|
4.7.7
Rechtsklick sperren
Man kann seinen Besuchern das Kontextmenü sperren. Ob man das tun sollte oder will, ist eine andere Sache. Technisch geht es so:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/transitional.dtd">
<html>
<head>
<title>Meine erste Test-Seite</title>
<script language="JavaScript1.5" type="text/javascript">
document.onmousedown = clickit;
function clickit ()
{
if (event.button == 2)
{
alert("Ist nix!");
}
}
</script>
</head>
<body>
</body>
</html>

|
|
|
4.7.8
Zuletzt geändert
Manchmal kann es interessant sein, wann ein Dokument das letzte Mal geändert wurde:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/transitional.dtd">
<html>
<head>
<title>Meine erste Test-Seite</title>
<script language="JavaScript1.5" type="text/javascript">
var msg = "Zuletzt geändert: "+document.lastModified;
document.write(msg);
</script>
</head>
<body>
</body>
</html>

|
|
|
4.7.9
Hover-Bilder
Bilder, die sich bei Berührung mit dem Mauszeiger verändern - ein Lieblings-Spielzeug von Webdesignern! Wir haben eine moderne, auf dem DOM basierende Lösung zusammengestellt. Daraus folgt, dass dieser Code nur mit neuen, DOM-unterstützenden Browsern funktioniert.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/transitional.dtd">
<html>
<head>
<title>Meine erste Test-Seite</title>
<script language="JavaScript1.5" type="text/javascript">
function changepic(id)
{
// Bild-Objekt holen via ID
var bild = document.getElementById(id);
// Bild-URL holen
var bildurl = bild.src;
// URL in Endung und Rest aufteilen
var ausdruck = /^(.+)((\.jpg)|(\.gif)|(\.jpeg))$/;
ausdruck.exec(bildurl);
// b: Beginn
var b = RegExp.$1;
// e: Endung
var e = RegExp.$2;
// Wenn Beginn ein _h enthält, also schon
// gehovert ist...
if (b.search(/_h$/) != -1)
{
// _h wieder entfernen, neue URL setzen
var ausdruck2 = /^(.+)_h/;
ausdruck2.exec(b);
bild.src = RegExp.$1+e;
}
else
{
// _h anfügen, neue URL setzen
bild.src = b+"_h"+e;
}
}
</script>
</head>
<body>
<img src="bild.jpg" onmouseover="changepic('b1')" onmouseout="changepic('b1')" id="b1">
</body>
</html>
Das Schöne an unserer Lösung: mit Bild-Namen haben wir nichts zu tun, solange das Bild, das bei Berührung erscheint, ein _h vor der Endung trägt. bild1.jpg und bild1_h.jpg sind ein solches Paar. Das Script erkennt die Endungen .gif, .jpg und .jpeg, Original-Bilder dürfen logischerweise auch kein _h im Dateinamen enthalten.
Um ein Bild berührungssensitiv zu machen, müssen Sie die beiden Event-Handler onmouseover="changepic('b1')" und onmouseout="changepic('b1')" hinzufügen. b1 ist in diesem Fall die ID des Bildes, die ebenfalls explizit gesetzt sein muss.
|
|
|
4.7.10
Pirate Framing verhindern
Pirate Framing nennt man das Übernehmen fremder Seiten in eigenen Frames. Das ist unschön und meist auch nicht erlaubt. Um sich gegen solche Taktiken zu schützen, kann man folgenden Code verwenden:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/transitional.dtd">
<html>
<head>
<title>Meine erste Test-Seite</title>
<script language="JavaScript1.5" type="text/javascript">
if (top.frames.length > 0)
{
top.location.href = self.location;
}
</script>
</head>
<body>
</body>
</html>
|
|
|
4.7.11
Zufallsgenerierte Ausgaben
Das folgende Script demonstriert einen einfachen Zufallsgenerator:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/transitional.dtd">
<html>
<head>
<title>Meine erste Test-Seite</title>
<script language="JavaScript1.5" type="text/javascript">
var alles = new Array("a", "b", "c", "d", "e");
var faktor = alles.length-1;
var myindex = Math.round(Math.random()*faktor);
document.write("Der Buchstabe des Tages: "+alles[myindex]);
</script>
</head>
<body>
</body>
</html>

|
|
|
|