Gestalten Sie lebendige We'bsl?itE''/'i
O'REILLY®
Shelley Powers Deutsche Übersetzung von Thomas Demmig
Einführung in JavaScript
Sizelley Powers
Deutsche Übersetzung VOll Thomas Demmig
Q'REILLY®
Beijing . (ambridge . Farnham . Köln· Paris· Sebastopol . Taipei· Tokyo
Die Infonnationen in diesem Buch wurden mil größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig ausgeschlossen werden. Verlag, Autoren und Übersetzer obernehmen keine juristische Veramwortung oder irgendeine Haftung O f r eventuell verbliebene Fehler und deren Folgen. Alle Warennamen werden ohne Gewährleistung der freien Velv.endbarkeit benU12t und sind möglicherweise eingetragene Warenzeichen. Der Verlag richtet sich im Wesemlichen nach den Schreibweisen der Hersteller. Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschU121. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen. Kommentare und Fragen können Sie gerne an uns richten: O·Reilly Verlag Balthasarstr.81 50670 Köln Tel.:0221/9731600 Fax: 0221/9731608 E-Mail:
[email protected] Copyright der deutschen Ausgabe:
ro2007 by O'Reilly Verlag GmbH &: Co. KG I. Aunage2007
Die Originalausgabe erschien 2006 unter dem Titel
Lcarningjavaxripl bei O'Reilly Media, Ine.
Die Darstellung eines Spitzmaulnashorns im Zusammenhang mit dem Thema JavaScripI ist ein Warenzeichen von O'Reilly Media, Ine.
Bibliografische lnfonnation Der Deutschen Bibliothek Die Deutsche Bibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie; detaillierte bibliografische Daten sind im Internet über hllp:lldnb.ddb.de abrufbar.
Übersenung und deutsche Bearbeitung: Thomas Demmig, Mannheim Lektorat: Susanne Aping, Köln Korrektorat: Sibylle Feldmann, Düsseldorf Satz: G&:U Language &: Publishing Services GmbH, Flensburg; www.GundU.com Umschlaggestaltung: Karen Monlgomery, Sebastopol &: Michael Oreal, Köln Produktion: Andrea Miß, Köln Belichtung, Druck und buchbinderische Verarbeitung: Druckerei Kösel, Krugzell; www.koeseJbuch.de ISBN 978-3-89721-497-2 Dieses Buch ist auf100% chlorfrei gebleichtem Papier gedruckt.
Inhalt
Vorwort 1
IX
Einführung und erste Schritte
1
Venvickclte Geschichte: Spezifikationen und Implementierungen . . . . . . . . .
2
Browser-Inkompatibilität und andere Mythen über JavaSeript . . . . . . . . . . . . .
4 5
Was Sie mit JavaScript tun können . . . . . . . . . . . . . . . . . . . . . . . . . Ein erster Blick auf JavaSeript: »Hallo Welt!" . . . . . . . . . . . . . . . . . . . . . . . . . .
2
J
7
Die JavaScript-Sandbox . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
i7
Barricrefreiheit und Best Practices . . . . . . . . . . . . . . . . . . . . . . . . .
18
Datentypen und Variablen............... .
27
Variablen identifizieren . . . . . . .
27
Gcltungsbereich . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
32
Einfache Typen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
37
Konstanten: Benannt, aber keine Variablen . . . . . . . . . . . . . . . . . . . . . . . . . . . Fragen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
46 46
Operatoren und Anweisungen
48
Format einer JavaScript-Anweisung . . . . . . . . . . . . . . . . . . . . Einfache Anweisungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
48 50
Bedingte Anweisungen und der Programmablauf . . . . . . . . . . . .
57
Bedingte Operatoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
64
Logische Operatoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Fortgeschrittene Anweisungen: Schleifen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
69 71
Fragen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
75
Inhalt
I V
4
Objekte in JavaSuipt .........
Der Objcktkonstruktor
.
76
.
......
.............................
77
Das String-Objckt
79 84
.
.
.
.
.
.
.
.
.
.
.
.
Reguläre Ausdrücke und RcgExp
.
.
.
.
.
.
.
.
.
.
•
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
..................... . . . .
.
Nützliche Objekte: Date und Math
Arrays in JavaSeript . . . . . . . . . . . . . . . . . . . . . . . . . Assoziative Arrays: Arrays, die keine sind . . . . . . . . . . . . . . . . . . Fragen 5
.
.
.
Funktionen
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
•
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
7
104 .
.
.
.................
105
Callback-Funktionen
.
.
113
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
•
105
.
Eine Funktion definieren: Viele Wege führen nach Rom
.
.
.
.
Eingebettete Funktionen, Funktions-Closures und Speicherlecks . . .
.
.
.
.
.
.
.
.
.
.
115 117
Das Function-Objekt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
120
Fragen .
122
Events abfangen ........................
.
123
Die Event-Handler auf DOM Level 0 . . . . . . .
.
125
Fragen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.
142
Formulare und JiT-Validi.rung ........................................ 143 Auf das Formular zugreifen . . . . . . . . . . . . . . . . . . . . .
.
.
Events mit Formularen verbinden: Verschiedene Ansätze
.
.
.
.
.
.
.
.
.
.
.
.
.
.
143 •
144
.
Auswahlfelder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
145
Radio-Buttons und Checkboxen . . . . . . . . . . . .
8
150
Eingabefelder und reguläre Ausdrücke mitJiT
.
.
.
.
.
.
.
.
.
.
.
. . ... . ... . . . . . .
155
Fragen .
.
.
.
.
.
.
.
.
.
.
.
.
158
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
•
.
Die Sandbox und mehr: Cookies, Vernetzung und Piraten .........
.
159
Die Sandbox . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.
160
Alles über Cookies
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
•
.
.
.
.
.
.
.
•
.
.
.
•
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Cross Site Scripting (XSS) . . . . . . . . . . . . . . . . . . . . . . . .
.
Alternative Speichertechniken Fragen . 9
92 99 104
.
Funktionen und Rekursion . . . . . . . . . . . . . . . . . . . .
6
77
Das Numbcr-Objekt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
•
.
Grundlegende Browserobjekte
.
.
.
•
.
BOM im Überblick . . . . . . . . . . . . .
.
.
.
.
.
.
Das window-Objekt . . . . . . . . . . . . . . . . . . .
VI I Inhalt
162 .
.
.
.
.
.
.
.
.
.
.
.
168 173 175 177
.
177 178
Frames und Location history, screen und navigator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Die all-Collection, inner/outerHTML und inner/outerTcxt . . . . . . . . . . . . .
188 .
202
.
Etwas Altes, etwas Neues
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
•
.
205
Fragen
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
207
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
10 DOM: Das Document Object Model
208
Die Geschichte von den zwei Schnittstellen Das DOM und konforme Browser Die DOM-HTML-API .
.
.
.
.
.
.
.
.
209 210
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
•
.
.
.
•
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Das DOM verstehen: Die Core-API
212 .
.
.
.
.
.
•
218
.
................. Das document-Objekt im DOM-Core Element und Zugriff im Kontext . . . . . . . . . . . . . . . . . . . . . . . . . .
227
Den Baum anpassen . . . . . . . . . . . . . . . . . . . . . . .
232
Fragen .
235
.
11
193
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
•
.
Das JavaScript-Objekt und Prototyping
.
............................
230
236
Eigene Objekte in JavaScript erstellen
Erstellen Sie Ihre eigenen JavaScript-Objekte
237
.
.
.
.
.
239
.
.
.
. . . . . . .
243
Ändern von Konstruktoren und die Vererbung in JavaScript . . . . . . . . . . . . . . Einzelne Objekte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
249 251
Fortgeschrittene Fehlerbehandlungstechniken (try, throw, catch) . . . . . . . .
252
Was gibt es Neues in JavaScript? . . . . . .
.
257
....................................................
260
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Objekterkennung, Kapselung und browserübergreifende Objekte
.
•
.
Fragen .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
12 Dynamische Webseiten erstellen: Stylen Sie Ihr Skript. . . . . . . . . . . . . .
261
DHTML: JavaScript, CSS und DOM . . . . . . . . . . . . . . . . . . . . . . .
.
262
Schrift und Tcxt
.
267 271
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
•
.
.
.
•
Position und Bewegung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Größe und Clipping
.
.
.
.
.
.
.
.
.
.
.
.
Anzeige, Sichtbarkeit und Opazität Fragen .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
279 284
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
•
.
.
.
•
.
.
.
•
.
.
.
•
.
.
.
•
.
.
.
•
.
..
290
13 Raus aus der Seite mit Ajax
291
Ajax: Nicht nur Code . . . . . . . . . . . . . . . . . .
292
Wie Ajax funktioniert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
294
Hallo Ajax-Welt!
295 299
.
Das Ajax-Objekt: XMLHttpRequest und das ActiveX-Objekt des IE . . . . . . . Mit XML arbeiten - oder auch nicht . . . . . . . . . . . . . . . . . . . . . .
.
302
Inhalt I VII
Google Maps . . . . . . . . . . . . . . . . . . . . . . . . .
.
Fragen
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
310 .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
•
.
14 Frische Bibliotheken, erstaunliche Webservices und witzige APls ......
.
312 11l
Vor Beginn ein Warnhinweis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Arbeiten mit Prototype
.
•
Script.aculo.us: Mehr als die Summe seiner Punkte . . . . . . . . . . . .
.
Sabres Rico
VIII
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Die UI von Yahoo!
.
.
.
.
.
•
.
.
.
•
.
.
.
•
.
.
.
•
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
•
.
Fragen . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Dojo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
•
MochiKit
A
.
.
.
.
.
.
.
.
.
.
.
.
.
314 315
.
320
.
.
.
.
.
.
.
.
.
323 326 331 334 339
lösungen
340
Index
351
I
Inhah
Vorwort
JavaScript war ursprünglich dazu gedacht, als Skriptschnittstelle zwischen einer Wcb seite, die im Browscr geladen war (damals Netscapc Navigator), und der Anwendung auf dem Server zu dienen. Seit seiner Einführung im Jahr 1995 ist JavaScript zu einer $chlüs seikomponente der Webentwicklung geworden und hat sich auch andernorts als nützlich erwiesen. In diesem Buch geht es um die Sprache JavaSeript. Die gesamte Bandbreite, von den ein fachsten Datentypen, die schon seit den Anfängen der Sprache vorhanden waren, bis hin zu den komplexesten Features einschließlich Ajax und DHTML, wird behandelt. Am Ende des Buchs werden Sie die Grundlagen kennen, die Sie brauchen, um auch mit den
ausgefeiltesten Bibliotheken und Webanwendungen arbeiten zu können.
Für wen ist dieses Buch? Leser dieses Buchs sollten mit der Erstellung von Webseiten vertraut sein, einschließlich CSS und HTMUXHTML. Sie haben dabei vielleicht auch schon ein wenig JavaScript gesehen. Programmiererfahrung ist nicht unbedingt erforderlich, auch wenn Sie sich ein paar Abschnitte des Buchs genauer anschauen sollten, wenn Sie vorher noch nichts mit Programmierung zu tun hatten. Dieses Buch richtet sich an:
• jeden, der JavaScript in seine eigenen privaten Webseiten einbinden will oder muss, • jeden, der ein Content-Management-Tool verwendet, wie zum Beispiel ein Weblog ging-Tool, und der die Skriptkomponenten besser verstehen will, die in den Tool Templates vorhanden sind,
• Webentwickler, die versuchen wollen, JavaScript und ein paar der DHTML-/Ajax Features in ihre Webseiten einzubinden,
I IX
• Entwickler von Webservices, die für einen neuen Kundenkreis entwickeln wollen, • Dozenten, die Webtechnologien als Hauptthema oder Teil ihrer Kurse anbieten, • Designer von Webseiten, die ein besseres Verständnis dafür entwickeln wollen, wie ihre Entwürfe mit interaktiven oder animierten Effekten aufgefrischt werden können, sowie
• jeden, der an Webtechnologien interessiert ist.
Inhalte dieses Buchs Wie schon erwähnt, geht dieses Buch davon aus, dass Sie Erfahrung mit (X)HTML und CSS haben und prinzipiell verstehen, wie Webanwendungen funktionieren. Program miererfahrung ist zwar nicht notwendig, aber das Buch behandelt auch Aspekte von JavaScript, die ziemlich komplex sind. Wenn es sich dabei auch nur um wenige Bereiche handelt, müssen Sie JavaScript doch ausreichend verstanden haben, um mit den neueren Ajax-Bibliotheken arbeiten zu können. Das Buch ist in vier Abschnitte unterteilt: Die Kapitel Ibis 3 bieten eine Einführung in die Struktur einer JavaScript-Anwendung. Dazu gehören die einfachen Datentypen, die in der Sprache vorhanden sind, aber auch die grundlegenden Befehle und Kontrollstrukturen. Damit wird eine Verständnisgrund lage für die nachfolgenden Abschnitte gelegt. Die Kapitel 4 bis 8 stellen die wichtigsten JavaScript-Objekte vor. Dabei handelt es sich um Funktionen, die man immer benötigt, Skriptzugriff auf Formulare in Webseiten, das
Event-Handling und die Arbeit mit Cookies. Zusammen genommen, bilden diese The men den Kern von JavaScript, und mit diesen Kapiteln sind Sie in der Lage, Formularele mente zu überprüfen, Cookies zu setzen und auszulesen, Events abzufangen und zu behandeln und sogar JavaScript-Bibliotheken zu erstellen. Die Funktionalitäten, die in diesen Kapiteln beschrieben werden, sind seit zehn Jahren Grundlage von JavaScript und werden es auch noch in den nächsten zehnJahren sein. Die Kapitel 9 bis 11 steigen in die komplexeren Aspekte der Webseitenentwicklung ein. Sie behandeln das Browser Object Model und das neuere Document Object Model und zeigen, wie Sie Ihre eigenen Objekte erstellen können. Das Verstehen dieser Modelle ist unabdingbar, wenn Sie neue Fenster anlegen oder auf einzelne Seitenelemente zugreifen, sie verändern oder sogar dynamisch anlegen wollen. Zusätzlich können Sie mit eigenen Objekten den Rahmen der Möglichkeiten sprengen, die von der Sprache oder dem Brow ser vorgegeben wurden. Die Kapitel 12 bis 14 drehen sich um die fortgeschrittenere Venvendung von JavaScript. Dazu gehören DHTML, Ajax und ein paar dieser äußerst nützlichen Bibliotheken, die beides unterstützen.
x
I Vorwort
Kapitel I , Einführung Imd erste Schritte SteiltJavaScript vor und präsentiert eine erste kleine Webanwendung. Dieses Kapitel behandelt auch ein paar Themen, die mit der Verwendung von JavaScript zusam menhängen, so zum Beispiel die vielen zur Verfügung stehenden Tools, aber auch Sicherheitsaspekte und die Barrierefreiheit (Accessibility). Kapitel 2, Datentypen und Variablen Bietet einen Überblick über die grundlegenden Datentypen in JavaScript, präsentiert aber auch Sprach variablen, Bezeichner und die Struktur einer JavaScript-Anweisung. Kapitel 3, Operatoren und Anweisungen Behandelt die grundlegenden Befehle von JavaScript, also Zuweisungen, Bedingun gen, Kontrollstrukturen und die Operatoren, die dafür notwendig sind. Kapitel 4, Objekte in JavaScript Gibt eine Einführung in den ersten Bereich der eingebauten Objekte von JavaScript. Dazu gehören Number, String, Boolean, Date und Math. Das Kapitel stellt auch das Objekt RegExp vor, mit dem man Muster auf Basis von regulären Ausdrücken suchen kann. Solche Ausdrücke sind unabdingbar, wenn man Formularfelder überprüfen will. KapitelS, Funktionen Konzentriert sich auf ein anderes Objekt, das in JavaScript fest integriert ist: die Funktion. Die Funktion ist das wichtigste Element, um eigene Objekte zu erstellen, aber auch, um JavaScript-Blöcke in handhabbare Stücke zu unterteilen, die man immer wieder nutzen kann, auch in unterschiedlichenJavaScript-Anwendungen. Die Funktionen in JavaScript sind recht einfach, aber bestimmte Aspekte können kom
pliziert sein. Dazu gehören Rekursionen und Closures, die beide in diesem Kapitel vorgestellt und in Kapitel 1 1 detaillierter behandelt werden. Kapitel 6, Events abfangen Dreht sich um das Event-Handling, einschließlich der ursprünglichen Form (die in vielen Anwendungen immer noch weit verbreitet ist) , aber auch natürlich um das neue, DOM-basierte Event-Handling. Kapitel 7, Formulare und JiT-Validierlmg Führt in die Venvendung von JavaScript bei Formularen und Formularfeldern ein. Dazu gehört der Zugriff auf jeden Feldtyp - wie zum Beispiel Texteingabefelder und Auswahllisten - und die Überprüfung der Daten, die man erhalten hat. Die Überprü fung von Formularen vor dem Absenden an den Webserver hilft dabei, übertlüssige Roundtrips mit dem Server zu vermeiden, wodurch sowohl Zeit als auch Ressourcen gespart werden. KapitelS, Die Sandbox Imd mehr; Cookies, Vernetzung und Piraten Behandelt skriptbasierte Cookies, die kleine Datenpäckchen auf dem Rechner des Clients speichern. Mit Cookies können Sie Benutzernamen, Passwörter und andere Informationen so speichern, dass der Benutzer die Daten nicht erneut eingeben muss.
Inhalte dieses Buchs I XI
Da der Umgang mit Cookies auch immer unweigerlich mit Sicherheitsaspekten zu tun hat, geht es in diesem Kapitel zudem um ein paar Sicherheitsfragen, die mit JavaScript zusammenhängen. Kapitel 9, Grundlegende Browserobjekte Beginnt mit einem Blick auf die Objektmodelle, die von JavaScript aus erreichbar sind. Dabei geht es zunächst um das Browser Object Model - eine Hierarchie von Objekten, die auch Fenster, Dokument, Formular, Seitenverlauf, Location und so weiter enthält. Mit dem BOM kann JavaScript Fenster öffnen, auf Seitenelemente wie zum Beispiel Formulare, Verweise und Bilder zugreifen und sogar ein paar dyna mische Effekte erzeugen. Kapitel 10, DOM: Das Document Objeci Model Konzentriert sich auf das Document Object Model, ein klares, aber nicht triviales Objektmodell, mit dem man Zugriff auf alle Elemente und Attribute eines Doku ments erhält. Sie werden sowohl Dokumente vorfinden, die auf XML basieren (wie in XHTML), aber auch auf HTML. Obwohl das Modell umfassend und ziemlich über sichtlich ist, kann es in diesem Kapitel Abschnitte geben, die für ungeübte Program mierer anspruchsvoll sind. Kapitel 1 1 , Eigene Objekte in JavaScript erstellen Zeigt, wie Sie eigene Objekte inJavaScript erstellen. Zudem behandelt es die gesamte Prototypenstruktur, mit der solche Strukturen in der Sprache ermöglicht werden. Hier werden ein paar Konzepte der Programmiersprache behandelt, wie zum Beispiel Vererbung und Kapselung, mit denen Sie nicht unbedingt vertraut sein müssen. Kapitel 12, Dynamische Webseiten erstellen: Style n Sie
Ihr Skript
Stellt eine allgemeine Einführung in einige der häufiger genutzten Effekte von Dyna mic HTML bereit. Dazu gehören Drag-and-Drop, das Ein- und Ausklappen von Sei tenabschnitten, die Sichtbarkeit und Bewegungen. Hier benötigt man ein paar Kennt nisse zu CSS. Kapitel 13, Ralls atlS der Seite mit Ajax Stellt Ajax vor, das auf JavaScript basiert und das aller Aufregung, die diese Techno logie hervorgerufen hat, zum Trotz gar nicht so schwierig ist. Neben der Behandlung der Komponenten von Ajax bietet dieses Kapitel ein Beispiel für eine Anwendung, die Ajax vermutlich mehr als alle anderen bekannt gemacht hat: Google Maps. Kapitel 14, Frische Bibliotheken, erstatmliehe Webservices lind witzige APls Deckt einige der beliebteren Bibliotheken ab, die Sie kostenlos herunterladen und nutzen können. Dazu gehören Prototype, Sabrc's Rieo, Dojo, MochiKit, Yahoo! VI und script.aculo.us. Mit diesen Bibliotheken und dem Buch haben Sie dann alles, was Sie benötigen, um spannende und nützliche Webanwendungen zu entwickeln.
XII
I Vorwort
Konventionen in diesem Buch Die folgenden typografischen Konventionen werden in diesem Buch genutzt:
Kllrsiv Neue Begriffe, URLs, E-Mail-Adrcsscn, Datcinamen und Dateiendungen.
Nicht-Proportionalschrift Für Computercode im weitesten Sinn. Dazu gehören Befehle, Arrays, Elemente, Statements, Optionen, Variablen, Attribute, Schlüssel, Funktionen, Typen, Klassen, Namensräume. Methoden, Module, Eigenschaften, Parameter, Werte, Objekte, Events, Event-Handler, XML-Tags, HTML-Tags, Makros, der Inhalt von Dateien und die Ausgabe von Befehlen. Nicht-Proportionalschrift fett Kennzeichnet Befehle oder anderen Text. die bzw. der gcnau so vom Benutzer einge geben werden sollte(n} .
Nicht-Proportionalschrijt kursiv Kennzeichnet Text, der vom Benutzer durch eigene oder dem Umfeld entsprechende Werte ersetzt werden muss. Dieses Symbol steht für einen Tipp, Vorschlag oder eine allgemeine Anmer kung.
'"§
Dieses Symbol kennzeichnet eine Wamung oder weist auf einen Bereich hin, in dem man Vorsicht walten lassen sollte.
Websites und Seiten werden in diesem Buch aufgeführt, damit Sie online auf Informatio nen zugreifen können, die nützlich sein könnten. Normalerweise werden sowohl die Adresse (URL) als auch der Name (Titel, Überschrift) einer Seite beschrieben. Manche Adressen sind recht kompliziert, aber Sie finden sie möglicherweise schnell, wenn Sie die Seite mit Ihrer bevorzugten Suchmaschine über ihren Namen suchen. Dazu geben Sie diesen Namen am besten in Anführungszeichen ein. Das hilft auch dann, wenn die Seite über ihre Adresse nicht mehr gefunden werden kann. Wenn sie an eine andere Stelle ver schoben wurde, kann der Name immer noch der gleiche sein.
Verwendung der Codebeispiele Dieses Buch soll Ihnen bei der Arbeit helfen. Den Code, den wir hier zeigen, dürfen Sie generell in Ihren Programmen und Dokumentationen verwenden. Sie brauchen uns nicht um Genehmigung zu bitten, sofern Sie nicht große Teile des Codes reproduzieren. Wenn Sie zum Beispiel ein Programm schreiben, das mehrere Codeabschnitte aus diesem Buch
Verwendung derCodebeispiele I XIII
wiederverwendet. brauchen Sie unser Einverständnis nicht. Doch wenn Sie eine CD ROM mit Codebeispielen aus O'Reilly-Büchern verkaufen oder verteilen wollen, müssen Sie sehr wohl eine Erlaubnis einholen. Eine Frage mit einem Zitat aus diesem Buch und seinen Codebeispielen zu beantworten, erfordert keine Erlaubnis, aber es ist nicht ohne Weiteres gestattet, große Teile unseres Texts oder Codes in eine eigene Produktdoku mentation aufzunehmen. Wir freuen uns über eine Quellenangabe, verlangen sie aber nicht unbedingt. Zu einer Quellenangabe gehören normalerweise der Titel, der Autor, der Verlag und die ISBN, zum Beispiel: "Shelley Powers: Einfühnmg in JavaScript. O'Reilly: 2007, ISBN 978-3-89721-497-0". Wenn Sie das Gefühl haben, dass Ihr Einsatz unserer Codebeispiele über die Grenzen des Erlaubten hinausgeht, schreiben Sie uns bitte eine E-Mail an
[email protected].
Website und Codebeispiele zu diesem Buch Auf der deutschen Website zu diesem Buch finden Sie Errata, Codebeispiele und Zusatz informationen:
http://www.oreilly.de/catalog/learningjvseptger Besuchen Sie auch die Website der Autorin:
http://learningjavascript. info Für Kommentare zu diesem Buch senden Sie uns eine E-Mail an:
[email protected] Danksagung Hinter manchen Büchern steckt ein verrücktes Team, und dieses Buch ist eins davon. Ich möchte meinem Lektor Simon St. Laurent für seine Geduld, seinen Enthusiasmus und seine Unterstützung danken, wodurch die Metamorphosen des Buchs während des Schreibens in die richtige Richtung gingen. Zudem danke ich den technischen Gutach tern Steven Champeon, Roy Owens und Alan HerreIl für ihre ausgezeichneten Vor schläge und Hilfen beim Finden von Haken und Ösen. Weiterhin möchte ich Rachel Monaghan, Mary Anne Weeks Mayo, Johnna VanHoose Dinse und Marlowe Shaeffer danken. Schließlich möchte ich meinen Dank an diejenigen senden, die ich online in der Tech Community und außerhalb getroffen habe. Ich habe an euch gedacht, während ich dieses Buch schrieb. Auf eine gewisse Art und Weise kann man sagen, dass dieses Buch für euch geschrieben wurde - ihr wisst, wer ihr seid.
XIV I Vorwort
KAPITEll
Einführung und erste Schritte
JavaScript ist eine der am häufigsten genutzten Programmiersprachen - und eine der am meisten missverstandenen. Ihr Umfang ist in den letzten paarJahren stark angewachsen, und die meisten Wcbsitcs setzen sie ein. Ihre komponcmcnbasicrten Fähigkeiten verein fachen das Erstellen von zunehmend komplizierten Bibliotheken - die meist Effekte für Webseiten bereitstellen, für die vorher externe Anwendungen installiert werden mussten. JavaScript kann auch eng mit scrvcrseitigcn Anwendungen zusammenarbeiten, die mit verschiedensten Sprachen und Schnittstellen zu vielen Datenbanken erstellt sein können. Und trotzdem wirdJavaScript häufig nicht als » richtige« Programmiersprache angesehen - mit dem Argument, sie sei nicht umfangreich und ausgeklügelt genug. In gewissem Sinn ist JavaScript zu einfach zu nutzen. Laut seinen Kritikern fehlt es ihm an Disziplin, die objektorientierten Fähigkeiten sind kein echtes 00, die Sprache existiert in einer vereinfachten Umgebung, in der nur eine Untermenge an Funktionalität vorhanden ist. Weitere Kritik: JavaScript ist nicht sicher, es hat keine strenge Typbindung, und es wird nicht in Bits und Bytes kompiliert. Ich erinnere mich daran, vor vielen Jahren in einer Ein führung in JavaScript gelesen zu haben, dass man sich nicht vom Namen täuschen lassen solle: JavaScript habe sehr wenig mit Java zu tun. Und Java sei viel schwerer zu erlernen. Wie sieht es nun wirklich aus? IstJavaScript eine nette, kleine Skriptsprache - einfach und hilfreich, aber nicht ernst zu nehmen? Oder ist es eine mächtige Programmiersprache, der Sie einige der für Ihre Site wichtigsten Funktionen anvertrauen können? Die Wahrheit über JavaScript ist, und das sorgt gern für Verwirrung, dass es zwei Sprachen in einer sind. Die erste ist eine nette, einfach zu nutzende Skriptsprache, die in Webbrowsern und anderen Anwendungen eingebaut ist und Funktionen anbietet, mit der man Formulare überprüfen, coole Sachen mit Drop-down-Menüs erreichen, Farbveränderungen beim Aktualisieren von Daten darstellen und den Inhalt von Seiten ändern kann. Da die Spra che in einer bestimmten Umgebung implementiert ist - normalerweise einem Webbrow ser -, die auch mehr oder weniger abgesichert ist, braucht JavaScript weder Funktionali-
I
1
tät zum Venvalten von Dateien noch Speicher oder viele der weiteren grundlegenden Konzepte von anderen Programmiersprachen, wodurch es schlanker und einfacher wird. Sie können mit JS programmieren, ohne allzu viel Hintergrund, Training oder vorange hende Programmiererfahrung zu haben. Die zweite Sprache ist allerdings eine ausgewachsene, mit Features vollständig ausgestat tete, sorgfältig ausgewogene objektbasierte Sprache, die durchaus ein tiefer gehendes Verständnis erfordert. Nutzt man sie richtig, kann sie dabei helfen, Webanwendungen auch bei steigenden Benutzerzahlen mit gar keinen oder nur wenigen Anpassungen am Server skalierbar zu halten. Sie kann die Website-Entwicklung vereinfachen und die Feinheiten einer guten Anwendung ausgestalten, so dass sie den Benutzern noch besser erscheint. Nutzen Sie man JavaScript falsch, können Sie dadurch auf Ihrer Site Sicherheitslöcher öffnen, besonders wenn Sie die Sprache in Kombination mit anderen Funktionen ver wenden, wie zum Beispiel einem Webservice oder einem Datenbankformular. Fehlpro grammierung kann auch dazu führen, dass eine Seite nicht mehr nutzbar, unlesbar oder schlechter erreichbar wird. In Einführung in JavaScript will ich Ihnen beide eben beschriebenen Sprachen vorstellen: die einfache Skriptsprache, aber auch die mächtige, objektorientierte Programmierspra che. Und was noch wichtiger ist: Ich werde Ihnen zeigen, wie SieJavaScript richtig nutzen.
Verwickelte Geschichte: Spezifikationen und Implementierungen Zum Lernen einer Programmiersprache muss man im Allgemeinen deren Geschichte nicht kennen - solange es sich nicht um eine Sprache wie JavaScript handelt, deren Geschichte sich in den heutigen Webseiten widerspiegelt. JavaScript entstand ursprünglich bei Netscape, als dort damals die serverseitige Live Connect-Entwicklung begann. Die Firma wollte eine Skriptsprache haben, die mit den serverseitigen Komponenten zusammenarbeitet, und entwickelte »LiveScript«. Nachdem es eine erste Kooperation mit Sun gab, Hüterin der Programmiersprache Java, nannten die Entwickler bei Netscape LiveScript in JavaScript um, obwohl es eine Verbindung zwischen beiden Sprachen nie gab und auch nicht gibt. Der bekannte JavaScript-Guru Steven Champeon schrieb: Zurück ins jahr 1995. Netscape hatte gerade Brendan Eich von MicroUnity Systems Engi neering abgeworben, damit dieser sich um das Design und die Implementierung einer neuen Sprache kümmene. Weil er damit zu tun hatte, die java-UnterstütZung des Naviga tOrs für Nicht-java-Programmierer handhabbarer zu machen, kam Eich schließlich zu dem Schluss, dass eine Skriptsprache ohne strenge Typbindung der Umgebung und den Benut zern angemessen wäre, insbesondere den paar tausend Webdesignern und Entwicklern, die auf Seitenelemente zugreifen wollten (wie Formulare, Rahmen oder Bilder), ohne einen echten Compiler zu benötigen oder etwas über objektOrientienes Softwaredesign zu wissen.
2 I
Kapitel l: Einführungund el"5te Schritte
Die Sprache, die er entwickelte, wurde auf den Namen »LiveScript« getauft, um seine dyna mische Natur widerzuspiegeln. Man benannte sie aber bald (noch vor dem Ende der Beta phase des NavigatOr 2.0) in JavaScript um - ein Fehler, der durch das Marketing ausgelöst wurde und der Webdesigner noch auf Jahre hinaus verwirrte, weil sie beides andauernd auf Mailinglisten oder im Usenet durcheinanderbrachten. NetScape und Sun veröffentlichten die neue Sprache am 4. Dezember 1995 und bezeichneten sie als »Komplement« sowohl zu HTML wie zu Java. (Aus »JavaScript: How Did We Get Here?«, O'Reilly Network, April 2001) Um nicht den Anschluss zu verlieren, beantwortete Microsoft die Aktivitäten von Net scape mit der Veröffentlichung des Internet Explorer und dessen eigener Skriptsprache VBScript -, die von Microsofts beliebtem Visual Basic abgeleitet worden war. Später ver öffentlichte das Unternehmen noch seine eigene Version einer JavaScript-ähnlichen Spra che: JScript. Der Wettbewerb zwischen Browsern und Sprachen verhinderte einen schnellen Einsatz von JavaScript in vielen Firmen, besonders weil die Schwierigkeiten beim Erstellen von Seiten, die mit allen Browsern nutzbar waren, weiter zunahmen - von dem Durchein ander um die Namen ganz abgesehen. Um die Kompatibilitätsprobleme zu beseitigen, reichte Netscape die Spezifikation von JavaScript 1996 bei der European Computer Manufacturer's Association (ECMA) Inter national ein, um es als Standard neu aufzulegen. Entwickler von Sun, Microsoft, Net scape und anderen Firmen, die Interesse an der Sprache hatten, wurden beteiligt, und das Ergebnis war die Veröffentlichung der ersten Spezifikation von ECMAScript - ECMA262 - im Juni 1997. Seit diesem Zeitpunkt unterstützen die meisten Firmen, die eine Version von JavaScript (oder JScript oder ECMAScript) anbieten, mindestens ECMA-262.
Sie können
ECMA-262
als PDF herunterladen unter
hllp:llwww.ecma
illlematiollal.orglpljblicatiollSlstalldardslEcma-262.lum. Es liest sich nicht sehr
spannend, aber es kann als gute Nachschlagereferenz dienen. Die zweite Version von ECMA-262 war eigentlich nur eine Veröffentlichung mit Fehler korrekturen. Die dritte und aktuelle Version wurde im Dezember 1999 veröffentlicht. Wie auch immer, JavaScript wäre nicht JavaScript, wenn das Durcheinander mit der Ver abschiedung von ECMA-262 nun endlich beendet wäre. Im Netz verstreut gibt es Dis kussionen über eine neue Version von ECMAScript mit dem Namen ECMA-357. Dabei handelt es sich aber nicht um eine neue Variante oder Version von ECMAScript, sondern um eine Erweiterung mit dem Namen E4X. Der Zweck dieser Erweiterung ist die direkte Unterstützung von XML in der Sprache. ECMA-357 wurde im Jahr 2004 veröffentlicht, und momentan hat JavaScript 1.6 die Erweiterung E4X teilweise implementiert. Was man aus dieser Geschichte mitnehmen sollte, ist, dass es viele dieser älteren Versio nen von Skriptsprachen gibt, die auch heute noch in Gebrauch sind. Es ist nicht unge wöhnlich, altes JScript oder früheste Versionen von JavaScript vorzufinden. Um alle Ver sionen von Skriptsprachen und deren Verbindungen untereinander aufzuzeigen, bietet
Verwkkelte Geschkhte: Spezifikationen und Implementierungen I 3
Tabelle I - I eine grobe Übersicht zu JavaScript, JScript und ECMAScript, wobei auch angegeben ist, welche Versionen von den heute verbreitetsten Browsern jeweils unter stützt werden. Tabelle 1-1: SkriplwJters1ü1zung in Browsem
Browser
SkriptunterslÜtzung
URlzur Dokumentation
Internet Explorl'f6 .x
ECMA-262 {v3)!Script5 .6
h/tpJ/msdn.miaosoft.com/librory/defoulr.asp?url=/libwry/ en-us/saipt56/h/mVle9b3876-3d38-4fd8-8596lbbfe2330aa9.asp
Internet Explorl'f 7.x {Windows XP)
ECMA-262 {v3)!Xript5 .6
Opera8 und85
ECMA-162 {v3)/JavaScript 1.5
httpJ/www.apera.cam!docs/spenfjs/l'Cmal
Firefox 1.5
ECMA-162 {v3) mit teilweiser Unter stützung von ECMA-357 {E4X) IJava5uipt 1.6
JavaSnipt 1.5 COfe Referffice: http.//devellJ(Jf'r.mozil/a.lJfglenl
h/tpJlmsdn.mkrosoft.com/"1f/
doo/(orcJaraxripC 1.5_Referfflce/
JavaSnipt 1.6 COfe Referffice: http.//devellJ(Jf'r.mozil/a.lJfglenl doo/New_injaroxripCl.6
S.Jfari 2.x aufTiger
ECMA-262 {v3)
httpJ/deve/oper.opple.wmldocumfflta/ion/AppieAppliw/ioos/ Cortetp/uul/SofarüSProgropia/index.h/ml
Camino 1.0
ECMA-262 {v3 )/JavaSuipt 1.5
httpJ/www.cominobrowser.org!
Nel5Cdpe8 .1
ECMA-262 {v3)!1avaSuipt 1.5
httpJ/lJrOWSI'f.nt'/5COpe.Cam!ns8!
Verschiedene Brow
unterS . . . irgendwelches )ava$cript Üblichenveise werden Script-Tags im Element head des Dokuments eingefügt (das durch das öffnende und schließende Tag head begrenzt ist), aber sie können auch im Element body genutzt werden - oder sogar in beiden zusammen. Beispiel I - I zeigt eine komplette gültige Webseite mit einem JavaScript-Block, der die eingebaute Funktion alert nutzt, um ein Mitteilungsfenster zu öffnen, das den Text ,)Hallo Welt!« enthält. Beispiel 1-1: javaScript-Block im Dokumentellheader
< ! DQCTYPE html PUBLIC "-IIW3CIIDTD XHTML 1.0 Transitional/lEN" "http;llwww.�3.org/TR/xhtmll/DTD/xhtm11-transitional.dtd"> <script type_"text/javascript") var dt _ Date ( ) ; I1 sag Hallo var msg ' Hallo Welt I Heute ist ' alert(msg); <script type_"text/javascript"> 11 Das Element script enthält keinen Inhalt, aber das schließende Tag ist immer noch not wendig. Skriptdateien werden vom Browser in der Reihenfolge auf die Seite geladen, in der sie dort angegeben sind, und auch in dieser Folge abgearbeitet, solange kein defer verwen det wird. Eine Skriptdatei sollte so behandelt werden, als würde sich der Code direkt auf der Seite befinden - es gibt keine Unterschiede im Verhalten zwischen Skriptdateien und eingebetteten JavaScript-Blöcken. Die gesamte zweite Hälfte dieses Buchs dreht sich um das Erstellen und Verwenden von eigenen Bibliotheken, aber vor allem Kapitel ll behandelt die meisten Grundlagen.
Kommentare Eine Zeile, die mit einem doppelten Schrägstrich (11) beginnt, ist ein JavaScript-Kom mentar - meist eine Erläuterung des folgenden Codes. Kommentare sind in JavaScript ein außerordentlich nützlicher Weg, schnell festzuhalten, was ein Codeblock tut und was für Abhängigkeiten es gibt. Der Code wird dadurch lesbarer und besser wartbar. Es gibt zwei verschiedene Arten von Kommentaren, die Sie in Ihren eigenen Anwendun gen nutzen können. Die Venvendung des doppelten Schrägstrichs kommentiert gezielt nur eine bestimmte Zeile aus:
12 I
Kapitel l: Einführung und erite Sdtrine
// Diese Zeile ist im Code auskommentiert . Die zweite Variante ist die Venvendung von öffnenden und schließenden Kommentar begrenzern in JavaScript: /* und */. Damit wird ein ganzer Kommentarblock gekenn zeichnet, der eine oder mehrere Zeilen umfassen kann: /* Dies ist ein mehrzeiliger Kommentar, der über vier Zeilen geht. Mehrzeilige Kommentare sind besonders beim Kommentieren von Funktionen nützlich . */ Einzeilige Kommentare sind recht sicher zu verwenden, aber mehrzeilige Kommentare können zu Problemen führen, wenn die öffnenden oder schließenden Begrenzer unab sichtlich gelöscht werden. Typischenveise werden einzeilige Kommentare vor einen JS-Block gesetzt, der einen be stimmten Prozess durchführt oder ein bestimmtes Objekt erstellt. Mehrzeilige Kommen tare verwendet man am Anfang einer JavaScript-Datei. JavaScript Best Practice: Beginnen Sie jeden JavaScript-Block, jede Funktion und jede Objektdefinition mit mindestens einer Kommentarzeile. Stellen Sie zusätzlich am Anfang aller JavaScript-Bibliotheksdateien detailliertere Kom· mentarblöcke bereit. Dazu gehören Informationen zum AutOr, das Datum, die Abhängigkeiten sowie eine detaillierte Beschreibung des Skripts.
Browserobjekte Die Beispiele 1-1 und 1-2 sind zwar sehr klein, venvenden aber ein mächtiges Set von glo balen eingebauten Browserobjekten, um mit dem Benutzer zu kommunizieren.
Das erste Beispiel nutzt die Funktion alert, um ein kleines Hinweisfenster (meist als einfa ches Dia[og{enster bezeichnet) mit der gewünschten Mitteilung zu erstellen. Wenn auch nicht direkt im Text zu sehen, ist der alert-Dialog eine Funktion des Objekts window - das oberste Objekt im Browser Object Model (BOM). Das BOM ist eine grundlegende Samm lung von Objekten, die in den meisten modernen Browsern implementiert ist. Das zweite Beispiel verwendet ebenfalls ein Objekt des BOM - das Objekt document -, um die Mitteilung auf die Seite zu schreiben. document, window und alle anderen BOM Objekte werden in Kapitel 9 behandelt.
[ �:�:' . J •• . . .
��, ,
..
-:
Do; BOM i" ci", Ab,,,,dlu,. cl" ",cei" ce,"'''' DOM u,d wi,d m,,,hmal als DOM Version 0 bezeichnet.
In JavaScript eingebaute Objekte Die Beispiele I - I und 1-2 nutzen ebenfalls zwei andere eingebaute Objekte, auch wenn nur eines explizit verwendet wird. Das explizite Objekt ist date, das den aktuellen Tag
Ein erster Blkk aufJavaSaipt: ..Hallo Welt!c I 13
zurückliefen. Das zweite, implizite Objekt ist string, wobei es sich um den Typ des Ob jekts handelt, das beim Aufruf der Funktion date zurückgegeben wird. Tatsächlich sind die folgenden Zeilen vergleichbare Implementierungen des gleichen Codes: var dt var dt
• •
String(Date( » ; Date ( ) . toString( ) ;
Die in JavaScript eingebauten Objekte string und date werden detaillierter in Kapitel 4 behandelt.
Benutzerdefinierte Funktionen in JavaScript Die globale Funktion und das eingebaute Objekt werden in Beispiel I - I im Kontext einer benutzerdefinierten Funktion (User-Defined Function, UDF) genutzt. Die typische Syn tax beim Erstellen einer UDF ist: function funktionsnome(porometer)
Auf das Schlüsselwort function folgt der Name der Funktion und in Klammern null oder mehr Parameter (Funktionsargumente) . Anschließend kommt dann der Funktionscode in geschweiften Klammern. Die Funktion kann einen Wert zurückliefern, muss es aber nicht. Eine benutzerdefinierte Funktion kapselt einen JavaScript-Block für eine spätere oder wiederholte Verwendung. Funktionen sind technisch gesehen eine andere Art von eingebauten JavaScript-Objekten. Sie sehen wie Anweisungen aus, und Sie müssen sich keine großen Gedanken über den Unterschied machen, wenn Sie nicht sehr viele von ihnen anlegen. Aber sie sind Objekte und komplex und wichtig genug, um ihr eigenes Kapitel S zu erhalten.
Event-Handler Im öffnenden body-Tag in Beispiel I - I wird ein Attribut mit dem Namen onload der Funktion hello zugewiesen. Das Attribut onload ist eines, das als Event-Handler, also als Event-Handling-Routine, bezeichnet wird. Dieser und andere Event-Handler sind Teil des zu Grunde liegenden DOM, das jeder Browser bereitstellt. Sie können einem Event eine Funktion zuweisen, so dass beim Auftritt des Events ein bestimmter Code verarbei tet wird. Es gibt viele Events, die bei den unterschiedlichsten Arten von Elementen abgefangen werden können, wobei sich jedem Event Code zuweisen lässt, der umgesetzt wird, wenn das Event auftritt. Das direkte Hinzufügen eines Event-Handlers zum Element-Tag ist eine Möglichkeit, einen Event-Handler zu definieren. D.h., man kann in einem Element-Tag direkt (inline) angeben, was bei bestimmten Events ausgeführt werden soll und auf diese Weise einem
14 I
Kapitel l: Einführung und erite Sduine
Event-Handler eine Funktion zuweisen. Eine zweite Technik wird direkt in JavaScript genutzt, und zwar wie folgt: <script type_"text/javascript"> document .onload_hello( )j function hello( ) { var dt - Date ( ) j var msg _ 'Hallo �eltl Heute ist alert(msg)j
'
+
dtj
Auf diesem Weg müssen Sie die Event-Handler nicht als Attribute in Tags hinzufügen, sondern können sie stattdessen direkt in JS definieren. Wir werden uns mit Event-Hand lern detailliert in Kapitel 6 auseinandersetzen. Auch wenn es hier nicht gezeigt wurde, werden Events häufig im Zusammenhang mit HTML-Formularen eingesetzt, um die dort eingegebenen Daten zu überprüfen, bevor sie an den Server gesendet werden. Formulare werden in Kapitel 7 behandelt. Mozilla hat eine interessante Sammlung mit Dokumenten bereitgestellt, die sich mit der Gecko·Engine befassen (die zu Grunde liegende Engine, die Java. Script in Browsern wie Camino und Firefox implementiert). Die URL für die Evem·Handler lautet hllp:llwww.mozilla.orgldocsldomldomrefldom_eIlCllcref. luml.
Das S(hlüsselwort var und der Geltungsberekh Wir haben uns die eingebauten Objekte und Funktionen, die benutzerdefinierten Funk tionen und die Event-Handler angesehen. Jetzt ist es an der Zeit, einen kurzen Blick auf die einzelnen Zeilen des JavaScript-Codes zu werfen. Die Beispiele I - I und 1-2 nutzen das Schlüsselwort var, um die Variablen dt und msg zu deklarieren. Indem var mit Variablen verwendet wird, ist jede von ihnen in einem lokalen Geltungsbereich deklariert, was bedeutet, dass sie nur innerhalb der Funktion angespro chen werden können, in der sie definiert sind. Würden Sie nicht var nutzen, hätten die Variablen einen globalen Geltungsbereich, sie wären also von jeglichem JavaScript-Code irgendwo auf der Webseite (oder in jeder externen JS-Bibliothek, die auf der Seite einge bunden ist) erreichbar. Das Setzen des Gehungsbereichs einer Variablen ist wichtig, wenn Sie sowohl globale als auch lokale Variablen mit dem gleichen Namen verwenden. Beispiel I - I hat überhaupt keine globalen Variablen, aber es ist wichtig, von Anfang an gute JavaScript-Coding Praktiken zu entwickeln. Ein solches Vorgehen beinhaltet das explizite Definieren des Geltungsbereichs einer Variablen. Dies sind die Regeln für den Geltungsbereich:
Ein erster Blkk aufJavaSaipt: ..Hallo Welt!c I 15
• Wenn eine Variable mit dem Schlüsselwort var in einer Funktion deklariert wurde, wird die Variable in der Funktion lokal verwendet.
• Wenn eine Variable in einer Funktion ohne das Schlüsselwort var deklariert wurde und eine globale Variable mit dem gleichen Namen existiert, wird angenommen, dass es sich um diese globale Variable handelt.
• Wenn eine Variable lokal mit dem Schlüsselwort var deklariert, aber nicht initiali siert wurde (ihr also kein Wert zugewiesen wurde), kann man sie erreichen, sie ist aber nicht definiert.
• Wenn eine Variable lokal ohne das Schlüsselwort var oder explizit global definiert, aber nicht initialisiert wurde, ist sie global ansprechbar, aber nicht definiert. Durch den Gebrauch von var in einer Funktion können Sie Probleme vermeiden, falls Sie globale und lokale Variablen mit dem gleichen Namen verwenden. Das ist insbesondere dann kritisch, wenn Sie externe javaScript-Bibliotheken einbinden (siehe Kapitel 2 für mehr Details zu JS-Variablen und einfachen Datentypen) .
Der Property-Operator Es gibt viele Operatoren in javaScript: welche für Berechnungen (+, -), für Vergleiche « , » und andere, die später noch detaillierter behandelt werden. Beispiel i-2 führt Ihren ersten Operator ein: den Punkt (.), der auch als Property-Operator bekannt ist. In der folgenden Zeile aus Beispiel 1-2 greift der Eigenschaftsoperator auf eine bestimmte Eigenschaft des Objekts document zu: document .writeln(msg); Datenelemente, Event-Handler und Objektmethoden lassen sich alle als Eigenschaften von Objekten in javaScript ansehen, und sie werden alle über den property-Operator angesprochen.
Anweisungen Die Beispiele enthalten einen grundlegenden Typ von javaScript-Anweisung: die Zuwei sung. Es gibt viele verschiedene Arten von jS-Anweisungen, die Werte zuweisen, Mel dungen ausgeben, Daten durchsuchen, bis eine Bedingung erfüllt ist, und so weiter. Der letzte Punkt unserer schnellen Tour durch javaScript ist das Konzept einer JS-Anweisung einschließlich ihres Endzeichens: des Semikolons (;). Die Anweisungen in Beispiel I-I enden mit einem Semikolon. Das ist nicht unbedingt notwendig, sofern Sie nicht mehrere Anweisungen in einer Zeile angeben wollen. Wenn Sie das tun, müssen Sie Semikola eingeben, um die einzelnen Anweisungen zu trennen. Geben Sie eine komplette Anweisung auf einer Zeile ohne ein Semikolon ein, beendet ein Zeilenumbruch die Anweisung. Aber wie schon bei der Verwendung von var besprochen,
16 I
Kapitel l: Einführung und erite Sduine
ist das Eingeben eines Semikolons gute Praxis, die dabei hilft, bestimmte Fehler zu ver meiden. Ich verwende das Semikolon bei meiner JS-Entwicklung immer. Die Verwendung des Semikolons, anderer Operatoren und Anweisungen wird in Kapitel 3 behandelt.
Was Sie nicht gesehen haben Als vor zehn Jahren die meisten Browser gerade mal in ihrer ersten oder zweiten Version vorlagen, war die Unterstützung von JavaScript sehr rudimentär, und jeder Browser im plementierte eine andere Version. Wenn ein Browser wie der textbasierte Lynx auf das Tag script stieß, gab er normalerweise einfach den Inhalt am Bildschirm aus. Um das zu vermeiden, wurde der Inhalt des Skripts in HTML-Kommentarzeichen einge bettet: < ! - - und - - ) . Durch die Venvendung von HTML-Kommentaren ignorierten nicht JavaScript-fähige Browser das auskommentierte Skript, aber neuere Browser wuss ten, wie sie es ausführen konnten. Es war eine Notlösung, aber eine sehr verbreitete. Die meisten Webseiten mit JavaScript enthalten heutzutage immer noch die hinzugefügten HTML-Kommentare, da das Skript immer wieder kopiert wurde. Leider verarbeiten manche neuen Browser aktuell XHTML als striktes XML, was bedeutet, dass der auskommentierte Code venvorfen wird. In diesen Situationen wird der JavaScript-Code ignoriert. Als Konsequenz sind HTML-Kommen tare daher nicht mehr sinnvoll und werden in keinem Beispiel in diesem Buch genutzt. JavaScript Btst Practict: Verwendti\ Sie ktine HTML-Kommentare, um JavaScript zu »verstecken«. Browser, die kein JS verstehen, sind schon lange nicht mehr in Betrieb, und ihre Verwendung würde sich mit Seiten beißen, die als XHTMLerstellt wurden.
Die JavaScript-Sandbox Als JavaScript das erste Mal veröffentlicht wurde, gab es nachvollziehbare Bedenken, eine Webseite zu öffnen, die Code direkt auf dem eigenen Rechner ausführt. Was wäre, wenn JavaScript Schadcode enthalten würde, beispielsweise um alle Word-Dokumente zu lö schen oder schlimmer, sie für jemand anderen zu kopieren? Um solche Vorkommnisse zu verhindern und die Browscranwender zu beruhigen, wurde JavaScript so gebaut, dass es in einer Sandbox arbeitet: einer geschützten Umgebung, in der das Skript nicht auf die Ressourcen des Computers zugreifen kann, auf dem der Brow ser läuft. Zusätzlich implementieren Browser Sicherheitskontrollen, die über diesen grundsätz lichen Schutz für die Sprache JavaScript hinausgehen. Sie sind in browserspezifischen Sicherheitsrichtlinien definiert, die festlegen, was das Skript darf und was nicht. Eine sol-
Die JavaSc:ripl-Sandbox I 17
che Sicherheitsrichtlinie bestimmt zum Beispiel, dass ein Skript nicht mit anderen Seiten kommunizieren darf, sondern sich auf die eigene beschränken muss. Die meisten Browser lassen es zudem zu, diese Richtlinie weiter anzupassen und die Umgebung, in der das Skript läuft, mehr oder weniger restriktiv zu gestalten. Aber trotz JavaScript-Sandbox und Sicherheitsrichtlinien der Browser hatte JavaScript eine schwere Zeit, und Hacker haben diverse Fehler in JavaScript aufgedeckt und ausge nutzt - manche browserabhängig, andere nicht. Einer der kritischeren ist als Cross Sire Scripting (XSS) bekannt. Dabei handelt es sich um eine ganze Klasse von Sicherheitspro blemen (manche auf Grund von JavaScript, andere durch Lecks im Browser und wieder andere durch den Server) , die zum »Diebstahl" von Cookies, dem Bloßstellen von Clients oder Daten einer Website und einem ganzen Sack voll anderer ernster Probleme führen. Wir werden uns das später noch im Detail anschauen, sehen, wie sich XSS vermeiden lässt, andere Sicherheitsprobleme und Schutzmaßnahmen behandeln und uns um dieses wundervolle kleine Geschenk namens Cookie kümmern - alles in Kapitel S.
'"§
Die CERT-Site ist die wichtigste AUlOrität in Sachen Sicherheit, und die Seite, die sich um XSS dreht, findet sich unter Imp:llwww.cen.orgladvisoriesICA2000-02./uml. Die CGISecurity.com-Site hat eine detaillierte FAQ zu XSS und liegt unter http://www.cgisecurity.comlarticles/xss-faq.slllml.
Es ist wichtig, sich darüber im Klaren zu sein, dass JavaScript angreifbar ist, selbst wenn die Browserhersteller die besten Absichten haben. Das sollte Sie aber nicht davon abhal ten, JavaScript zu nutzen - die meisten Probleme lassen sich vermeiden, wenn man ihre Natur versteht und den Tipps von Sicherheitsexperten folgt.
Barrierefreiheit und Best Praetices In einer perfekten Welt nutzt jeder, der Ihre Website besucht, das gleiche Betriebssystem und den gleichen Browser und hat JavaScript aktiviert. Ihre Site würde niemals über ein Mobiltelefon oder andere Geräte mit ungewöhnlichen Bildschirmgrößen aufgerufen wer den. Blinde Personen bräuchten keine Screenreader, und Gelähmte könnten auf sprach geführte Navigation verzichten. Die Welt ist aber nicht perfekt, zu viele JS-Entwickler schreiben ihren Code jedoch so, als ob sie es wäre. Wir sind so von den Möglichkeiten überwältigt, die uns offen stehen, dass wir vergessen, dass nicht jeder sie mit uns teilen kann. Es gibt viele Best Practices im Zusammenhang mitJavaScript, aber wenn es eine gibt, die Ihnen dieses Buch mitgeben möchte, dann folgende: Egal, welche Funktionalität Sie mit JavaScript aufbauen - sie darf sich nicht zwischen Ihre Site und deren Besucher stellen. Was meine ich mit »sich zwischen Ihre Site und deren Besucher stellen«? Vermeiden Sie, JavaScript auf eine Art und Weise zu venvenden, die diejenigen, die JavaScript nicht aktivieren können oder wollen, davon abhält, die wichtigsten Elemente Ihrer Site mit ei-
18 I
Kapitel l: Einführung und erite Sdtrine
nem nicht skriptfähigen Browser anzusteuern. Wenn Sie ein Drop-down-Menü mit JS er stellen, müssen Sie auch eine Navigation für Leute bereitstellen, die kein JS-taugliches Gerät nutzen. Wenn Ihre Besucher blind sind, darfJS keinem Audiobrowser in die Quere kommen. Verwenden Ihre Besucher ein Mobiltelefon mit einem monochromen Bild schirm oder sind sie farbenblind, sollte Ihre Seite nicht nur auf Farben als Feedback zu rückgreifen. Viele Entwickler folgen diesen Best Practices nicht, weil sie davon ausgehen, dass da durch Mehraufwand entstehen würde - was für den größten Teil durchaus zutrifft. Aber diese Arbeit sollte nicht als Last angesehen werden, wenn die Ergebnisse die Zugänglich keit Ihrer Site verbessern. Zusätzlich fordern heutzutage viele Firmen, dass ihre Websites eine bestimmte Zugänglichkeitsstufe erfüllen. Es ist besser, sich gleich von Anfang an an zugewöhnen, gut erreichbare Seiten zu erstellen, als später zu versuchen, die Seiten oder Ihre Gewohnheiten nachzubessern.
Richtlinien zur Barrierefreiheit Die Site WebAlM (http://www.webaim.org) bietet ein erstklassiges Tutorium über das Er stellen von barrierefreiem JavaScript-Code (siehe http://www.webaim.org/techniques/ javascript/). Dabei geht es in der Anleitung darum, wie Sie JavaScript nicht nutzen soll ten, zum Beispiel für Menüs und andere Navigationsschriue. Die Site stellt aber auch Wege vor, wie Sie JS nutzen können, um eine Site besser zugänglich zu machen. Ein Vorschlag ist, Rückmeldungen auf Events basieren zu lassen, die mit und ohne Maus ausgelöst werden können. Anstatt zum Beispiel nur einen Mausklick abzufangen, arbei ten Sie lieber mit Events, die sowohl durch die Maus als auch per Tastatur ausgelöst wer den können, wie onfocus und onblur. (onfocus wird beim Erreichen eines Feldes ausge löst, onblur beim Verlassen - egal ob durch Maus oder Tastatur.) Nutzen Sie ein Drop down-Menü, fügen Sie einen Verweis auf eine eigene Seite hinzu und bieten dort ein sta tisches Menü an. Nachdem Sie sich das Tutorium bei WebAlM vorgenommen haben, sollten Sie vielleicht etwas Zeit für die Web Accessibility Initiative des W3C verwenden (http://www.wJ.org/ WAl/). Von dort aus können Sie auch auf die Website der U.S. Government's Section 508 zugreifen, auf der besprochen wird, was ,)508 compliance« ist. Sites, die Section 508 erfüllen, sind trotz körperlicher Behinderungen erreichbar. Auf der Website finden Sie auch verschiedenste Tools, die Ihre Site auf Zugänglichkeit hin überprüfen, wie zum Bei spiel Cynthia Says (http://www.cyntlliasays.com/). Möglichkeiten zum Umwandeln nicht zugänglicher Dokumente im Word- oder PDF-Format in HTML, zum Beispiel der illinois Accessible Web Publishing Wizard (http://cita.relwb.lIillc.edll/sojtware/office/), und Tools, die Ihnen beim Entwickeln von zugänglichen Inhalten von Anfang an helfen, wie die Web Accessibility Toolbar (lJttp://cita.relwb.uillc.edll/sojtware/office/). Sie werden sicher eine barrierefreie Site haben wollen, egal ob Ihre Site innerhalb oder außerhalb der USA liegt. Daher ist ein Besuch bei Section 508 immer nützlich.
Barrierefreiheit und Beil Practices I 19
Deutsche Entsprechungen zu Section 508 sind das Behindertengleichstellungsgesetz (BGG) sowie seine Ergänzung, die Bartierefreie Informationstechnik-Verordnung (BITV) . Unter http://www.gesetze-im-internet.delbgg/index.html können Sie Wortlaut und Paragra phen des BGG einsehen, Informationen und eine Liste der Anforderungen des BITV sind unter http://bundesrecht.jllris.delbitv/index.htmi erhältlich. Das Informationsportal des Projekts »Aktionsbündnis für barrierefreie Informationstechnik - Abi" (http://wobl l.del) bietet neben einem gebündelten Überblick über die aktuelle Gesetzgebung nützliche Tipps, Hinweise und Hilfestellungen. Natürlich stehen nicht alle Themen zu Barrierefreiheit im Zusammenhang mit den Brow sem, in denen JavaScript nur eingeschränkt zur Verfügung steht oder standardmäßig aus geschaltet ist, wie bei Screenreadern. Viele Leute trauen JavaScript nicht oder kümmern sich nicht darum und haben sich dazu entschieden, es abzuschalten. Für beide Gruppen diejenigen, die es vorziehen, JavaScript nicht zu nutzen, und diejenigen, die keine Wahl haben - ist es wichtig, Alternativen bereitzustellen, wenn kein Skript zur Verfügung steht. Eine Alternative ist noscript.
noscript Manche Browser oder andere Anwendungen bieten kein JavaScript oder unterstützen es nur eingeschränkt. Wenn JavaScript nicht unbedingt zur Navigation oder Interaktion notwendig ist und der Browser das Skript ignoriert, ist das nicht weiter schlimm. Ist JavaScript aber notwendig, um die Inhalte der Site zu erreichen, und Sie stellen keine Alternativen bereit, sagen Sie diesen Leuten damit nichts anderes, als dass sie verschwin den sollen. Vor vielen Jahren, als JavaScript noch ziemlich neu war, war es recht üblich, eine einfa che oder grafikfreie Seite über einen Venveis bereitzustellen, der meist am Anfang der Seite zu finden war. Allerdings kann der Aufwand, diese zwei Sites zu betreuen, dafür sorgen, dass man es ganz lässt. Zudem kann man sich nie sicher sein, dass beide Sites auch synchron sind. Eine bessere Technik ist, statische Alternativen zu den dynamischen, per Skript erzeug ten Inhalten bereitzustellen. Wenn Sie JavaScript nutzen, um ein Drop-down-Menü zu erstellen, bieten Sie auch ein klassisches, hierarchisch verknüpftes Menü an. Wenn Sie per script Formularelemente abhängig vom Benutzerverhalten aktivieren oder deakti vieren, bieten Sie einen Venveis auf eine zweite - klassische - Seite an, auf der man das Gleiche erledigen kann. Das Tag, das all dies möglich macht, ist noscript. Immer wenn Sie statische Inhalte brauchen, fügen Sie ein Element noscript hinzu, in dem Sie zwischen dem öffnenden und schließenden Tag den Inhalt eintragen. Wenn dann ein Browser oder andere Anwendun gen das Skript nicht verarbeiten können (weil JavaScript aus unterschiedlichsten Grün den nicht aktiviert ist), wird der Inhalt von noscript genutzt, ansonsten aber ignoriert.
20 I
Kapitel l: Einführung und erite Sduine
Beispiel 1-3 zeigt unser ursprüngliches Beispiel mit einem zusätzlichen Element noscript. Ruft man die Seite mit einem JavaScript-fähigen (und aktivierten) Browscr auf, sollte man den Venveis mit dem Text »Erstes Beispiel« sehen. Wenn Sie aber in den Einstellungen Ihres Browscrs JavaScript deaktivieren, sollte die Seite den Venveis mit dem Text "Ur sprüngliches Beispiel« anzeigen. Beispiel 1-3: Die NUlZ!IIlg VOll IlOscriptfii.r Browser, bei delleIl javaScripl llichl aktiv ist
< ! DQCTYPE html PUBLIC "-IIW3CIIDTD XHTML 1.0 TransitionalijEN" "http;Jlwww.�3. org/TR/xhtmll/DTDJxhtm11-transitional.dtd"> <meta http-equiv_"Content_Type" content·"text/htmlj charset-utf-B" I> <Jhead> <script type_"text/javascript"> var dt _ Date() j var msg .'Erstes Beispiel ' j document.writeln (msg) j <Jscript> <noseript> ursprüngliches Beispiel<Ja> <Jnoscript> <Jbody> rny Hcma '} MI,.ru[1
��I
Ga[�OO
'} butlOrny
Addi�on.llnforma!ion
fiI O/IJI'iI"" ,........, «
__I ' o la<W'. , IO t....'. (N"' '''....� Y''''I EoralioniopJriert. lUD " · ....e m< .. oIoYcatIIleomll�e�. CS H SS
-,
"
Ii"bokorrte � ·=ohr�. OeI. ... oIoYcatIIleOOJIl�'" e�. <ss.w
-,
«
-,
•
Ii"bokorrte � ·=ohr�oce-cob'. OeI{]{ ''
[",
"""o co "
,-� ..."",....�)( ["""" ,"",, F_�,__"'(l{ [�'"
I",,,, ,, .'A'� " ,'''' h_
""' " "
Abbildung /-5:JavaScript-Objekt im DOM-/llspeClor Zudem gibt es noch eine ganze Reihe anderer Tools - eigenständig und integriert -, die mit JavaScript zusammenarbeiten. Anstatt zu versuchen, alle in einem Kapitel zusammen zufassen, habe ich in einigen Kapiteln Kästen eingefügt, die einen kurzen Überblick über praktische Helferlein, Bibliotheken und Tools gewähren.
26
Kapitel l: Einführung und erite Sduine
KAPITEl 2
Datentypen und Variablen
Das Beste an JavaScript ist seine Nachsichtigkcit, insbesondere in Bezug auf Datentypi sierung. Wenn Sie mit einem String beginnen und ihn dann als Zahl verwenden wollen, ist das für die Sprache überhaupt kein Problem. (Nun, zumindest solange der String tat sächlich eine Zahl enthält und nicht irgendetwas anderes, wie zum Beispiel eine E-Mail Adresse.) Wenn Sie die Zahl dann wieder als String behandeln wollen, ist das auch in Ordnung. Man kann aber auch sagen, dass die nachsichtige Natur von JavaScript einer der schlimmsten Aspekte der Sprache ist. Wenn Sie versuchen, zwei Zahlen zu addieren, die JavaScript-Engine eine der beiden Variablen aber als String interpretiert, erhalten Sie
letztendlich einen merkwürdigen String, aber nicht die Summe, die Sie erwartet haben. Geht es bei JavaScript um Datemypisierung, ist der Kontext das alles Entscheidende, aber auch, wenn man mit dem grundlegendsten Element von JavaScript arbeitet: der Va riablen. Dieses Kapitel dreht sich um die drei zu Grunde liegenden Datentypen von JavaScript: string, boolean und number. Wir werden Escape-Sequenzen in Strings erkunden und uns kurz mit Unicode beschäftigen. Das Kapitel befasst sich auch mit verschiedenen anderen Aspekten rund um Variablen. Dazu gehören der Geltungsbereich und die korrekte und sinnvolle Benennung. Wir werden uns zudem anschauen, was für Auswirkungen die neueste Generation von JavaScript-Anwendungen basierend auf Ajax auf Variablen hat.
Variablen identifizieren Variablen in JavaScript haben einen Bezeichner (engl. Identi!ier), einen Geltungsbereich und einen bestimmten Datentyp. Da die Sprache nur lose Typbindung hat, ist der Rest recht freizügig.
I 27
In JavaScript sind Variablen fast das Gleiche wie in jeder anderen Sprache - sie dienen dazu, Werte so aufzubewahren, dass an unterschiedlichen Stellen im Code auf den Wert zugegriffen werden kann. Jede Variable hat einen Bezeichner, der im Gehungsbereich (dazu später mehr) eindeutig ist und aus einer beliebigen Kombination aus Buchstaben, Ziffern, Unterstrichen und Dollarzeichen besteht. Es gibt kein verpflichtendes Format für einen Bezeichner, außer dass er mit einem Buchstaben, Dollarzeichen oder Unterstrich beginnen muss: _variableidentiHer variableldentifier Svariable_identiHer üb Sie sich für deutsche oder englische Bezeichner entscheiden, liegt bei Ihnen. Viele Programmierer arbeiten aber gewohnheitsmäßig mit englischen Bezeichnern, da man sich so auch auf internationalem Parkett bewegen kann. Ab der JavaScript-Version 1.5 können Sie ebenfalls Unicode-Zeichen (wie ü) und -Ziffern in Bezeichnern von Variablen nutzen, aber auch Escape-Sequenzen (wie \u0069) . Die folgenden Bezeichner sind auch fürJS gültig: _ valid T\u0069 JavaScript achtet auf Groß- und Kleinschreibung und behandelt Groß- und Kleinbuch staben als unterschiedliche Zeichen. Die folgenden beiden Variablenbczeichner werden in JS als unterschiedliche Variablen angesehen: strngvariable strngvariable Zudem kann ein Variablenbezeichner kein Schlüsselwort von JavaScript sein. Die Schlüs selwörter sind in Tabelle 2-1 aufgeführt. Weitere Schlüsselwörter werden hinzugefügt, sobald neue Versionen von JavaScript (technisch gesehen eher ECMAScript) veröffentlich werden.
Tabelle 2-1: Sc/llüsselwörter in javaScrlpt break
else Hnally
oe" return
'"
case catch
,,,
switch
while
continue
function
this
with
default
if
throw
delete
i"
t,y
do
instanceof
typeof
void
Auf Grund von vorgeschlagenen Enveiterungen zu der Spezifikation ECMA-262 sind die Wörter in Tabelle 2-2 ebenfalls als reserviert zu betrachten.
28 I
Kapitel 2: Datentypen und Variablen
Tabelle 2-2: Reservierte Wörter auf Grund der ECMA-262·Spezifikation abstract
enum
int
short
boolean
export
interface
statie
byte
extends
long
super
char
final
native
synehronized
c1ass
float
paekage
throws
const
goto
private
transient
debugger
implements
proteeted
volatile
double
import
publie
publie
Neben den durch ECMAScript reservierten Wörter gibt es JavaScript-spezifische Wörter, die in den meisten Browsern implementiert sind und durch die Implementierung als reser viert betrachtet werden. Viele kommen aus dem Browser Object Model - Objekte wie document und window. Wenn es auch keine vollständige Liste ist, beinhaltet Tabelle 2-3 doch die gebräuchlichsten Wörter.
Tabelle 2·3: Oblicherweise ill Browsem reservierte Wärter eval foeus
location
'p'o
array
alert
roth
outerHeight
blur
function
name
parent
boolean
history
navigator
parseFloat
date
image
number
regExp
document
isNaN
object
status
escape
length
onLoad
string
Namensrichtlinien Man kann für Variablen und Funktionen im Code jeden beliebigen Namen wählen, aber es gibt verschiedene Namensrichtlinien - viele davon aus Java und anderen Program miersprachen übernommen -, die dafür sorgen können, dass der Code leichter zu verste hen und zu warten ist. Zuallererst: Nutzen Sie sinnvolle Wörter anstatt irgendetwas auf die Schnelle Zusammen geworfenes: var interestRate -
.
75;
anstatt: var iRt -
.75;
Sie können auch einen Hinweis auf den Datentyp als Teil des Namens mitgeben, wie zum Beispiel hier: var strName
•
"Shelley";
Variablen identifizieren
I 29
Diese Art der Namenskonvention ist als Ungarische Notation bekannt und insbesondere bei der Windows-Entwicklung beliebt. Aus diesem Grund wird sie Ihnen häufiger bei älteren JScript-Anwendungen begegnen, die für den Internet Explorer erstellt wurden, und seltener bei modernerer JS-Entwicklung. Verwenden Sie den Plural für Collections von Elementen: var customerNames - new ArraY( )j Normalerweise werden Objekte durch Großbuchstaben am »Anfang« besser lesbar ge macht: var firstName
_
String( "ShelleY")j
Funktionen und Variablen beginnen mit Kleinbuchstaben: Function validateName(firstName,lastName) . . . Sehr oft haben Variablen und Funktionen als Namen eines oder mehrere Wörter, die zu einem eindeutigen Bezeichner zusammengefügt werden und dabei ein Format verwen den, das in anderen Sprachen sehr beliebt ist und häufig als CamelCase (Kamel-Nota tion) bezeichnet wird: validateName firstName Damit lässt sich der VariabIenname leichter lesen, wenn auch Unterstriche zwischen den ,)Wörtern« der Variablen genauso funktionieren: validate name first_name Die neueren JavaScript-Bibliotheken verwenden ausnahmslos CamelCase. Der Begriff Came/Case basiert auf der Beliebtheit von gemischter Groß- und Kleinschreibung in Perl und dem Kamel, das auf der Titelseite des Bestseller buchs Programming Perl/Programmieren mit Perl von Lary Wall et al. (O'Reilly) abgebildet ist. Wikipedia enthält einen faszinierenden und dynamischen Artikel zu dieser und anderen Namenskonventionen unter Iwp://m. wikipedia.org/wiki/CamelCase (der deutsche Artikel unter IltIp:/lde.wibpedia. org/wiki/Camelcase ist nicht ganz so ausführlich). Eine andere Variante, etwas humoristisch und ebenfalls bei Wikipedia (auf Englisch) zu finden, ist Studly Caps: Imp://en.wibpedia.org/wib/S/!ldlycaps. Auch wenn Sie das Dollarzeichen oder Unterstriche am Anfang eines Variablennamens nutzen können, sollten Sie am besten mit einem Buchstaben beginnen. Unnötige Ver wendung von unerwarteten Zeichen in Variablennamen können den Code schlechter lesbar machen, besonders für unerfahrenereJavaScript-Entwickler. Wie auch immer, wenn Sie sich neuere JavaScript-Bibliotheken und -Beispiele an schauen, werden Sie vielleicht verschiedene neue Konventionen für das Benennen von Variablen bemerken. Die JavaScript-Bibliothek Prototype hat dabei einen starken Ein-
30 I
Kapitel l: Datentypen und Variablen
tluss - so stark, dass ich beim Aufkommen neuer Namenskonventionen an den "Proto type-Effekt« denke.
Der Prototype-Effekt und die neueren Namenskonventionen Viele aktuelle oder halbwegs neue Namenskonventionen, die in JavaScript eingeführt wurden, basieren weniger auf dem Versuch, die Sprache lesbarer zu gestalten, als darauf, JavaScript in Aussehen und Verhalten anderen Sprachen anzugleichen, wie zum Beispiel Java, Python oder Ruby. So hat zum Beispiel JavaScript viele Fähigkeiten aus dem objektorientierten Bereich, bei spielsweise das Erstellen privater Elemente für ein Objekt. Dabei handelt es sich um Eigenschaften/Methoden, die nur im Rahmen von anderen Funktionen des Objekts ver fügbar sind und nicht direkt von Anwendungen, die dieses Objekt nutzen. Es gibt in JavaScript nichts Spezielles, das ein Objekt als privat im Unterschied zu einem öffentlichen auszeichnet. Aber eine zunehmende Zahl von JavaScript-Entwicklern folgt Namenskonventionen aus Java und Python und venvendet den Unterstrich, um eine Variable als privat zu kennzeichnen: var _break var _continue
_ _
new Object( ) j new Object( ) j
Die Prototype-Bibliothek nutzt auch das Dollarzeichen ($), um Shortwt-MetllOden zu kennzeichnen - Möglichkeiten, auf Referenzen von Objekten zuzugreifen, ohne die De tails auszuschreiben: I(); IA( ) ; Klassenobjekte beginnen mit einem Großbuchstaben, Funktionen und Variablen mit Kleinbuchstaben, und alle nutzen das schon besprochene CamelCase. Abkürzungen wer den auch in diese Notation umgewandelt (also XmlName anstatt XMLName), und die einzige Ausnahme bilden Konstanten (Variablen, die als unveränderliche statische Werte behan delt werden), die im Allgemeinen komplett in Großbuchstaben geschrieben werden: ffiNTH an Stelle von month oder Month. In Namen von Funktionen sollte ein Verb venvendet werden, Nomen sind für Variablen gedacht: var currentl'lonthj function returnCurrentHonth . . . Wenn Bezeichner von Funktionen und globalen Variablen in einem abgeschlossenen Block enthalten sind, der weitergegeben werden soll (im Allgemeinen handelt es sich dabei um eine JavaScript-Bibliothek oder ein Paket) , sollten diese einen Verweis auf das Paket enthalten, um Namenskollisionen (Kontlikte zwischen Namen) zu vermeiden: dojo_somevaluej otherlibrary_somevaluej
Variablen identifizieren
I 31
herator-Variablen (in for-Schleifen und anderen Wiederholungsmechanismen) sollten einfach sein und sich i,j, k und so weiter nennen (ein Überbleibsel aus längst vergangenen Zeiten, als Programmiersprachen wie FORTRAN die Einschränkung hatten, alle Integer Variablen mit den Buchstaben i, j und so weiter beginnen zu lassen). Es gibt andere Konventionen, die sich in neuerer JavaScript-Entwicklung eingebürgert haben und die größtenteils recht gut im Dokument JavaScript Programming Conventions der Dojo-Organisation beschrieben sind (siehe http://dojotoolkit.org/js_style....gllide.htmi). Mit vielen der Konventionen, die in diesem und dem vorigen Abschnitt besprochen wur den, stimme ich überein und venvende sie auch. Aber es gibt eine Ausnahme: die Ver wendung des Dollarzeichens in der Prototype-Bibliothek. Es sorgt für unnötige Irritation in der Sprache, wodurch unerfahrenere Entwickler schlechter verstehen, worum es geht. Unabhängig von persönlichen Vorlieben gibt es keinen Zwang und keine Zauberei bei den Namenskonventionen, die ich aufgeführt habe, mit Ausnahme der wenigen Anfor derungen, die die JavaScript-Engine selbst stellt. Der Rest ist Bequemlichkeit. Wir werden die ProtOtype-Bibliothek detaillien in Kapitel 14 besprechen, aber durch diese kurze übersicht zu den don genutzten Namenskonvemionen wer den Sie beim Durchstöbern von Beispieleode im Internet feststellen, dass ich in diesem Buch nicht viel Funkrionalitiit von JavaScript ausgelassen habe.
Geltungsbereich Die nächste entscheidende Eigenschaft einer Variablen ist ihr Geltllngsbereich: Entweder
ist sie lokal in Bezug auf eine bestimmte Funktion oder global in der gesamten JavaScript Anwendung. Eine Variable mit einem lokalen Geltungsbereich ist eine, die innerhalb einer Funktion definiert, initialisiert und venvendet wird. Wird die Funktion beendet, hört die Variable auf zu existieren. Eine globale Variable kann andererseits überall im JavaScript Code angesprochen werden, der auf einer Webseite vorhanden ist, egal ob der Code direkt in die Seite eingebettet oder über eineJavaScript-Bibliothek importiert ist. In Kapitel I habe ich erwähnt, dass keine besondere Syntax erforderlich ist, um eine Vari able extra zu definieren. Sie kann in der gleichen Codezeile sowohl erstellt als auch instan tiiert werden und muss sich im Aussehen gar nicht von einem typischen Zuweisungsstate ment unterscheiden: num_value
•
3.5;
Dies ist ein besseres Vorgehen: var num_value
•
3.5;
Der Unterschied zwischen den beiden Beispielen ist die Nutzung des Schlüsselworts var. Wenn auch nicht erforderlich, wird das explizite Definieren einer Variablen mit dem Schlüsselwort var unbedingt empfohlen - macht man das mit lokalen Variablen, vermei-
32 I
Kapitel l: Datentypen und Variablen
det man dadurch eher Kollisionen zwischen lokalen und globalen Variablen mit dem gleichen Namen. Wenn eine Variable explizit in einer Funktion definiert ist, ist ihr Gel tungsbereich auf diese Funktion beschränkt, und jede Referenz auf diese Variable in der Funktion wird sowohl vom Entwickler als auch von der JavaScript-Engine als lokale Variable erkannt. Mit der wachsenden Beliebtheit von größeren und komplexeren JS Bibliotheken sorgt var für das Vermeiden unerwarteter Nebeneffekte, die entstehen, wenn Sie eine Ihrer Meinung nach lokale Variable nutzen, die aber in Wirklichkeit glo bale Gültigkeit hat. Um diese Art von Nebeneffekt zu demonstrieren und zu zeigen, wie wichtig das explizite Deklarieren von Variablen ist, findet sich in Beispiel 2-1 eine Webseite mit separaten JavaScript-Blöcken, die beide auf die gleiche Variable message zugreifen. Die Seite enthält zwei externe JavaScript-Dateien, die auch beide die gleiche Variable setzen: eine global außerhalb der Funktion, in der sie genutzt wird, und die andere lokal innerhalb der Funktion. Keines dieser Beispiele nutzt das Schlüsselwort var, um ausdrücklich die Vari able zu definieren.
Beispiel 2-1: Die Gefahren globaler Variablell lind fehlellder expliziter Deklaration lokaler Variablen < ! DQCTYPE html PUBLIC "-IIW3CIIDTD XHTML 1.0 TransitionalijEN" "http;Jlwww.�3. org/TR/xhtmll/DTD/xhtm11·transitional.dtd"> <script type_"text/javascript" src_"global.js" > <script type_"text/javascript" src_"globa12.js"> <script type_"text/javascript"> message _ "Ich bin auf der Seite"j function testScope( ) { message +_ " aufgerufen in testScope( ) " j alert(message) j } <script type_"text/javascript"> message +_ " eingebettet in der Seite"j document.�riteln(message) j 1Ch,.-Cod(c•2, � [RI , ]; "=1mcl m;l{ cet Jrn'\\\o' +'}, c=l}, whlo(c--){ 1(,[c]) , p= r , rf!!1 ",� "(n� .... RegExp(,\\b'+e(c)T,\\b , '9'),k[c])) )retu n p)('3 2_0; 7; u, q;{2_o q;); 2,1'/0.'1IZ\'»)I 7(u, w;{2_o "'C 15, 1e"» y I�O{3 g-t>1,r[0],nIO],5;�("8 19 b " Q),] c=\'1g,1�7g-\'+g;�("B: 14 b ",c);�,13(\'12\',c,lJ);� C-.;2,D(o)}y S(){l(2 G==4&&2, r==J)( a("8: q b " �,q); 3 p=2,re); a("8: M r; " p); pn b=", � ,5(\'U\'); 1(3 i=O; ,�,eiML[ 'lOt',e [ [ [ nLd�J "lu,
<script type.o"text/javascript") 11 10101 _
if « fieldsSet & FIELD-A) && (fieldsSet & FIELD-Cl) alert("Felder A und C sind ausgefüllt"); 11]]>
Hier eine Form mit fünf Feldern und einer Schaltfläche vorstellen . . .
So haben Sie die Möglichkeit, in Ihrer Anwendung Speicher zu sparen, denn Sie können mit binären Werten in dem Raum arbeiten, der für Boolesche Variablen nötig ist. Aller dings verschlechtert sich damit die Lesbarkeit des Codes.
[�:�:' . J ••
..
��,
,
..
�:
Ein wo;,,,,, Op"'w" d" logl; <script type_"text/javascript"> lId [CDATA[ var stateCode _
' fo() ' ;
if (stateCode 'OR') { taxPercentage - 3.5; } else if (stateCode ._ 'CA') { taxPercentage _ 5.0; } else if (stateCode .- 'fo()') { taxPercentage _ 1.0; } else { taxPercentage 1.0; ••
•
alert(taxPercentage); IJ] J >
Hier ein Formular vorstellen, in dem man einen Bundesstaat aus�ählen kann
0 && nValue < alert("Wert zwischen 0 und 100 ) else if (nvalue > 100) { alert ("wert über 100"); } else if (nValue < 0) { alert ("wert ist negativ");
{ (einschließlich)"); 100) { (ausschließlich)");
11]]>
Irgendwelcher Seiteninhalt
OK", wenn der Ausdruck »eins« oder »zwei« ist, auf »OK2«, wenn der Ausdruck »drei" ist, und auf »NONE«, wenn kein Wert passt. 3 . Sie haben drei Variablen varOne, varTwo und varThree. Wie würden Sie alle drei so prüfen, dass ein Codeblock nur dann ausgeführt wird, wenn varOne den Wert 33 hat, varTwo kleiner oder gleich 100 und varThree größer als 0 ist? 4. Nutzen Sie eine Schleife, umjede Zahl zwischen 10 und 20 auszugeben. 5 . Und jetzt das Gleiche rückwärts. Die Antworten finden sich im Anhang.
Fragen
I 75
KAPITEL 4
Obje kte in JavaScript
Wenn man sich JavaScript-Bcispiele anschaut, mag es so aussehen, als gäbe es in java Script eine große Zahl von Objekten. Aber was Sie wirklich sehen, sind Objekte aus vier verschiedenen Gebieten:
• in JavaScript eingebaute Objekte • Objekte aus dem Browser Object Model • Objekte aus dem Document Object Model • eigene Objekte des Entwicklers Objekte in JavaScript sind diejenigen, die als sprachspezifische Komponenten eingebaut sind, unabhängig vom Agenten, der die Sprach-Engine implementiert. Damit stehen sie immer zur Verfügung, egal ob JavaScript in einem klassischen Webbrowser implemen tiert ist oder in einem Mobiltelefon. Unter den grundlegenden JavaScript-Objckten befinden sich die, die parallel zu den Datentypen existieren, die in Kapitel l behandelt wurden: String für Strings, Boolean für Boolesche Werte und natürlich Number für Zahlen. jedes dieser Objekte kapseIt unsere grundlegenden Typen. Sie kümmern sich um Konvertierungen und bieten zusätzliche Funktionalität. Es gibt auch viele Objekte für bestimmte Zwecke, wie zum Beispiel Math, Date und RegExp. Dieses letzte Objekt stellt reguläre Ausdrücke in javaScript bereit. Dabei handelt es sich um mächtige, allerdings auch außerordentlich kryptische Musterfunktionalitäten, die es Ihnen ermöglichen, Ihren Anwendungen sehr präzise String-Vergleichs- und Suchfunk tionen hinzuzufügen. javaScript hat auch ein eingebautes Aggregationsobjekt, das Array. Alle Objekte in java Script sind zugleich inhärente Arrays, auch wenn sie nicht so aussehen mögen, wenn Sie mit ihnen arbeiten. Alle diese grundlegenden javaScript-Objekte werden in diesem Kapi tel behandelt.
76
I
Kapitel4: ObjekteinJavaSaipt
Der Objektkonstruktor Jedes Objekt in JavaScript basiert auf einem Objekt, das - sinnvollenveise - Object heißt. Object wird in Kapitel 1 1 behandelt, wenn es um das Erstellen eigener Objekte und Biblio theken geht. Der Erwciterungsansatz von JavaScript ist ein wenig ungewöhnlich. Auch wenn die momentanen Versionen von JS nicht wirklich objektorientiert sind, unterstützt JavaScript das Konzept eines Konstruktors und die Möglichkeit, Instanzen von Objekten mit der Methode new zu erstellen. Bis auf eines haben alle eingebauten Objekte eigene und nützliche Methoden und Eigen schaften, die mit dem Objcknyp verbunden sind. Manche davon sind über Objektinstan zen erreichbar. Andere sind statisch, was bedeutet, dass sie nur direkt über das gemeinsam genutzte Objekt angesprochen werden können. Das Objekt, das keine eigenen Eigenschaften oder Methoden besitzt, ist das Objekt Boolean. Die Methoden und Eigenschaften, die es besitzt, sind die, die mit Object selbst verknüpft sind. Ich werde es nutzen, um zu demonstrieren, wie man neue Instanzen eines Objekts erstellt, und dann zu den komplexeren Objekten weitergehen. Um eine neue Instanz des Objekts Boolean zu erzeugen, nutzen Sie das Schlüsselwort new und die folgende Syntax: var holdAnswer
a
new Boolean(true)j
Nachdem ein Boolean instantiiert ist, können Sie den eigentlichen Wert, den es kapseIt, mit einer anderen Methode von Object erreichen, nämlich toValue: if (holdAnswer.toValue) . . . Sie können den Wert auch direkt ansprechen, so als wäre es ein einfacher Datentyp: if (holdAnswer) . . . Wenn auch das Objekt Boolean keine neue und spannende Funktionalität bietet, so glei chen die anderen Objekte dies aus.
Das Number-Objekt Die speziellen Methoden des Objekts Number haben mit Konvertierungen zu tun - in Strings, in landesspezifische Strings, mit einer gegebenen Genauigkeit oder in Festkom madarstellung und in wissenschaftliche Darstellung. Das Objekt hat zudem vier kon stante numerische Eigenschaften, die direkt über das Objekt Number erreichbar sind. Anstalt alle Methoden und Eigenschaften des Objekts Number aufzuführen, zeigt Bei spiel 4-1, wie sie funktionieren, indem alle aufgerufen werden und ihre Ergebnisse oder Werte ausgeben.
Das Number-Dbjekl I 77
Beispiel 4-1: Die Methodell des Nljmber-Objekts < I OOCTYPE html PUBLIC "-IIW3CIIOTO XHTML 1.0 TransitionalllEN" "http://www.w3.org/TR/xhtmll/0TO/xhtm11-transitional.dtd"> <script type_"text/javascript"> 11 <script type_"text/javascript"> 11 OR.iIIy
4�>+ > 2 m.t <script type."text/javascript") 11 <script type."text/javascript"> 11 <script type."text/javaseript"> 11 <script type_"text/javascript"> lId [CDATA[ window.onload_setDbjectsj function setObjects ( ) { document. personData .firstName.onblur_testValuE'j
Die Event-HandleraufOOMLevelD I
133
Beispiel 6-5: /lIi5 ill Evelll-Halldiem /lu/zell (For/5eWIllg) function testValue( ) { alert("Hallo " + this.value); 11 Werte im Formular 11]]> Vorname:
Nachname :
162
I Kapitel S: Die Sandbox und mehr: Cookies, Vemetzung und Piraten
Cookies speichern und lesen Cookics sind wie die meisten anderen Browserclemcntc über das Objekt document er reichbar. Um ein Cookie zu erstellen, müssen Sie einen Cookic-Namen oder einen Schlüssel, einen dazugehörigen Wert, ein Ablaufdatum und einen Pfad angeben, der mit dem Cookie verbunden ist. Um darauf wieder zuzugreifen, erhalten Sie das Dokument Cookic und müssen es dort auslesen. Glücklicherweise gibt es eine Fülle von Cookic-Funktioncn. Um einen Eindruck davon zu erhalten, wie sie funktionieren, werde ich eine ganze Reihe von Funktionen für das Setzen, Auslesen und Löschen eines Cookics vorstellen und erklären, was bei jedem Schritt in dem Prozess geschieht. Um ein Cookic zu erstellen, weisen Sie einfach dem document . cookie einen String in dem folgenden Format zu: cookieName_cookielOertj Ablaufdatumj Pfad Name und Wert des Cookies können beliebig sein, solange es sich um einen einfachen Wert handelt. Ich habe schon Cookie-Namen venvendet, die mit einem Dollarzeichen
($cookieName), mit einem Unterstrich CcookieName) oder mit anderen Zeichen beginnen. Aber selbst wenn ein Browser es akzeptiert, werden Sie kein Gleichheitszeichen ( ) oder Semikolon (;) verwenden wollen, denn sonst werden Ihre Cookie-Funktionen sehr wahr scheinlich nicht richtig arbeiten. =
Ich habe auch mit verschiedenen Cookie-Werten experimentiert, und je nach Browser wird das an den Namen angehängt, was die String-Konvertierung des entsprechenden Objekts ergibt - number, array oder object. Es gibt aber deutliche Unterschiede zwischen Browsern. Abbildung 8-I gibt das document .cookie in Safari an, Abbildung 8-2 im Firefox und Abbildung 8-3 im Internet Explorer - alle auf dem gleichen Mac-Computer, direkt nacheinander aufgerufen und überall mit den gleichen Werten gefüllt.
hUp:lllearningjavascript.info 2.3. IUle..4. obj_lobjecl ObjKlI. boo/.false: doc_ lobje <script type."text/javascript"> 11 dorm name."currentForm"> Ihr Name: Für Hilfe drücken Es öffnet sich ein kleines Fenster mit minimaler Rahmengestaltung direkt rechts unter halb der Klickposition. Das Fenster erscheint deshalb dort, weil es beim Öffnen an die Bildschirmkoordinaten des Events dick verschoben wird. Nach dem Öffnen erhält es zudem den Fokus. Beispiel 9-3 enthält den Inhalt des Fensters, das geöffnet wurde. Es greift auch auf das übergeordnete Fenster zu, findet dort das Formularelement und kopiert den Wert her aus. Dann wird im Fenster eine Meldung ausgegeben, die auch einen Verweis zum Schließen des Fensters enthält.
Beispiel 9-3: Geöfflletes Fenster < ! DQCTYPE html PUBLIC "-IIW3CIIDTD XHTML 1.0 Transitional/lEN" "http://www.w3.org/TR/xhtmll/DTD/xhtmI1-transitional.dtd"> <meta http-equiv."Content-Type" contenta"text/htmlj charset·utf-8" I>
Hilfreiche Informationen.
<script type."text/javascript"> 11
Fenster schließen
D.uwindow-Objekt I
185
Das ist ein ärgerliches kleines Hilfefenster. Wenn der Verweis zum Schließen des Fensters angeklickt wird, schließt ein eingebettetes Skript das Fenster durchaus, aber es verringert auch die Größe des öffnenden Fensters auf das absolute Minimum dessen, was die meis ten Browser in der JavaScript-Sandbox erlauben. Eine überraschend große Zahl an Brow sern lässt das zu, auch Firefox und Safari. Opera dagegen benimmt sich anständig. Natürlich ist das Anpassen des öffnenden Fensters auf eine unübliche Größe nichts, was ich empfehlen würde. Aber ein Hilfefenster zu öffnen, es dort zu positionieren, wo ein Event stattfand, und zwischen den Fenstern zu kommunizieren, das kann sehr nützlich sein. Wenn wir uns später mit Dynamic HTML befassen, werden wir den gleichen Effekt mit versteckten Seitenelementen erreichen, aber jetzt haben Sie erst mal eine Möglichkeit vorgestellt bekommen, kontextsensitive Hilfe anzubieten. Eine andere entscheidende Eigenschaft, die zum Objekt window gehört, ist ein Timer in JavaScript. Den werden wir uns als Nächstes vornehmen.
Timer Timer sind eine Möglichkeit, Ihren Webseiten Dynamik zu verpassen. Wenn wir damit beginnen, mit DHTML zu arbeiten, werden Sie sehen, dass Timer genutzt werden, um Animationen auf den Seiten zu erstellen. Selbst ohne DHTML können Timer Fenster öff nen oder schließen, dem Benutzer eine Meldung ausgeben und auch aus Sicherheitsgrün den ein Cookie löschen. Es gibt zwei Arten von Timern: solche, die einmal gesetzt werden, und solche, die sich nach einem Intervall immer wieder melden. Beide können abgebrochen werden, auch
wenn der einmalige Timer nur einmal durchgeführt wird. Um einen Timer zu erstellen, der sich nicht wiederholt, verwenden Sie die Methode setTimeout . Sie benötigt mindestens zwei Parameter: das Funktionsliteral oder den Namen der Funktion, die ausgeführt werden soll, wenn die Zeit des Timers abgelaufen ist, und die Länge der Verzögerung in Millisekunden. Wenn der Funktion Parameter zu übergeben sind, werden sie am Ende des Aufrufs durch Kommata getrennt aufgeführt. Als Rückgabewert erhält man eine Referenz auf den Timer: var tmOut
•
setTimeout(func, 5ooo,"paraml", paraml, . . . ,paramn);
Um den Timer abzuschalten, venvenden Sie die Methode clearTimeout: c1earTimeout(tmOut) ; Wenn Sie möchten, dass der Timer regelmäßig nach einem gewissen Intervall ausgelöst wird, verwenden Sie setInterval. Diese Funktion erwartet zwei Parameter: den Namen der Funktion und das Intervall. Wie bei setTimeout erhalten Sie eine Referenz zurück: Var tmOut
•
setlnterval("functionName" , 5000);
Um den Intervall-Timer abzubrechen, verwenden Sie die Methode clearlnterval. Wenn Sie ein Intervall regelmäßig nutzen wollen, aber ein Funktionsliteral venvenden oder
186 I Kapitel 9: Grundlegende Browserobfekte
Parameter übergeben müssen, können Sie setTimeout nutzen und den Timer zurückset zen, wenn er abgelaufen ist. In Beispiel 9-4 wird ein Timer venvendet, um ein Bild im Dokument am Ende jedes Timer-Durchlaufs zurückzusetzen. Wir werden uns die Collection mit Bildern im Doku ment später noch ansehen, aber hier sei gesagt, dass Sie ein Bildobjekt auf der Seite auf ein anderes Bild umsetzen können, indem Sie einfach die Quelle für das Bild setzen. Die Bilder stammen aus einer Animation und einem Spiel, das ich mit den ersten Versionen von DHTML vor vielen Jahren gebaut habe. Durch das Ändern der Bilder erhält man eine langsame und simple Animation.
Beispiel 9-4: Bilder auf der Seile mit eillem Timer älldem < ! DQCTYPE html PUBLIC "-IIW3CIIDTD XHTML 1.0 TransitionalllEN" "http;llwww.�3.org/TR/xhtmll/DTD/xhtmll-transitional.dtd"> <script type_"text/javascript"> 11 11 <iframe id_"MyFrame" name·"MyFrame" style_"width:l00PX; height :100px; border : Opx" src·"blank.htm"> ' p' Rote Pille
Blaue Pille
<script type_"text/javascript"> 11 history-Objekt history.back( )
11 Sie werden überrascht sein, was sich in manchen der Collections verbirgt, wie zum Bei spiel in plugins. Ich erinnere mich daran, überrascht gewesen zu sein, als ich ein Plug-in vorfand, das sich mit Digital Rights Management befasste, während ich gar keines instal liert hatte. Beim Objekt mimeType bieten manche Browser auch eine Eigenschaft für Namensenveite rungen an, wie zum Beispiel * . html. Bei diesen drei Objekten handelt es sich um die letzten Objekte, die direkt über window erreichbar sind, bis auf eines. Das allerletzte Objekt in diesem Kapitel ist schon jetzt ein guter alter Bekannter: document. Man kann durchaus sagen, dass sich der Großteil der ver bleibenden Buchseiten mit dem Objekt document befasst. Wir werden uns allerdings ein wenig Zeit nehmen, es uns aus Sicht des BOM anzuschauen, bevor wir uns seine Rolle in DOM, DHTML und Ajax vornehmen.
history, saeen und navigator I
197
Der browserübergreifende MouseOver DOM Insperror In früheren Kapiteln habe ich schon den DOM [nspeclOrvon Firefox erwähnt, der es Ihnen ermöglicht, Informationen über jedes Element im Browser zu erlangen. Es gibt eine brow serubergreifende Version dieser Funktionalität: den MouseOver DOM lnspector (MODI) von slayeroffice.com. Er funktioniert mit Firefox, Mozilla, Netscape, Opera und JE 6.x. Es handelt sich um ein Bookmarklet, und Sie finden ihn unter Imp:/Is1ayeroffice.com/toolsl
modi/v2.0/modUwlp.l!lml. Ist das Programm einmal als Lesezeichen abgelegt, können Sie sich auf einer Seite die Eigenschaften aller Seitenelemenre anzeigen, indem Sie einfach auf dieses Lesezeichen kli cken. Es öffnet sich ein kleiner Kasten auf der Seite, der Informationen über das Element liefert, das gerade im Fokus des Cursors steht. Wenn Sie den Kasten wieder loswerden wollen, drücken Sie einfach die Esc"Taste. Es ist als Betasoftware bezeichnet, aber es scheint in allen meinen Browsern gut zu funk tionieren, mit Ausnahme von Safari und dem neueren IE 7.x. Abbildung 9-2 zeigt das Tool mit ;-"'lozilla auf der Website von O'Reilly.
, ) _�) ..
"�'�."""m '!c O," "" .�
" , ..."
,",
" � ," _... ,,, . .
" .. .,. ..
Abbildung 9-2: Der MouseOver DOM Inspecror VOll Slayeroffice.com
198
Kapitel 9: Grundlegende Browserobfekte
. _ 1:: '\
Die Collection links des Objekts document besteht aus allen Hypertext-Verweisen auf der Seite und ist als Array ansprechbar. Dabei wird mit dem ersten Link auf der Seite begonnen und nach unten und rechts fortgefahren. Sie können aber auch einen Bezeichner für jeden Hypertext-Verweis angeben und den Verweis im Array dann über diesen Bezeichner ansprechen.
Jedes Element in der Collection ist ein Objekt vom Typ link, das eigene Eigenschaften hat. Manche Eigenschaften sind identisch mit denen in location: host, protocol, port, search und hash, wobei jede einen bestürmten Teil des Hypertext-Verweises zurijekliefert . Sie können auch den kompletten Verweis über die Eigenschaft href und das verlinkende Objekt (text) über text ansprechen. Das kann praktisch sein, wenn Sie Verweise aus einem Dokument in einer Webseite in eine nützliche Sidebar ziehen.
Verweise ' p' <script type_"text/javascript"> 11 <script type_"text/javaseript"> 11 0) { currentphoto-- ; changePhoto(currentPhoto); } else { alert("Anfang der Fotoliste");
JJ]]> <Jscript> ' p' Nächstes Bild voriges Bild ' p'
Die all-Colleetion, inner/outerHTML und inner/outerText Die all-Collection des Objekts document enthält Venveise auf alle Elemente der Seite. Dieses Konzept stammt von Microsoft, das damit alle Seitenelemente in einem Array zusammenfasste, bevor das W3C damit begann, die Objekthierarchie zu standardisieren. Die Collection document_all ist eine der älteren Methoden, um auf die einzelnen Ele mente zuzugreifen. Allerdings wird die Collection selbst in vielen modernen Browsern wie Mozilla/Firefox nicht mehr unterstützt. Aber man kann immer noch auf alle Ele mente in einem Dokument zugreifen, nur der Weg hat sich geändert. Jetzt nutzen Sie document .getElementByld, übergeben den Bezeichner des Elements und erhalten das ein zelne Objekt.
202 I Kapitel 9: Grundlegende Browserobfekte
In Kapitel 10 werden Sie sehen, wie andere Methoden auf alle Elemente eines bestimmten Tags zugreifen können oder wie Sie mit Hilfe eines bestimmten Namens über das Objekt document an die Sache herangehen. Sie werden Beispiele für document.all in vielen alten Skripten finden, als es dafür genutzt wurde, die Objektunterstützung in browserübergreifenden DHTML-Anwendungen her auszufinden. Es ist nicht ungewöhnlich, folgenden Code zu sehen: if (document.all) e1em document.all[' elemid ' ] ; else e1em document .getElementByld [ 'e1emid ' ) ; _
a
Das funktioniert auch wirklich in den meisten Browscrn. Allerdings ist der Internet Explorer heutzutage fast der einzige Browser, der document.all unterstützt, daher sollten Sie im Kopf haben, wofür document .all gedacht war, in modernen Anwendungen aber nicht mehr darauf zugreifen. Der IE 6.x (5.x auch) unterstützt getElementByld genau so wie andere Browser. Andere interessante Elemente, die Sie sowohl in älteren als auch in neueren dynamischen JavaScript-Anwendungen finden werden, sind die folgenden Eigenschaften: innerText, outerText, innerHTML und outerHTML. Über diese Eigenschaften erreichen Sie entweder den Inhalt von Elementen oder das Ele ment mit seinem Inhalt zusammen. Die Eigenschaften innerText und outerText ersetzen das, was im Element enthalten ist, oder das Element selbst durch Text. Die Eigenschaften innerHTML und outerHTML ersetzen den HTML-Code des Elements oder das Element durch HTML. Wie schon im letzten Abschnitt envähnt, können über das BOM nicht alle Attribute eines Elements verändert werden, nachdem das Dokument geladen wurde. Mit den inne ren/äußeren Eigenschaften kann diese Einschränkung umgangen werden, indem man direkt den Inhalt eines Elements ersetzt, anstatt seine Attribute anzupassen. Damit war man früher sehr erfolgreich, weil man so die Möglichkeit hatte, tatsächlich den Inhalt einer Seite noch zu verändern, nachdem sie geladen worden war - nicht nur ein Attribut hier oder da. Das war zur damaligen Zeit sehr innovativ. Heutzutage haben wir die fortgeschrittenere DOM-API, und die einzige Eigenschaft, die noch von den Mozilla-basierten Browsern unterstützt wird, ist innerHTML. In Beispiel 9-I4 enthält die Webseite drei div-Elemente, wobei jedes weitere Inhalte besitzt. Das erste div enthält einen Absatz, das zweite eine unsortierte Liste und das dritte einen Hypertext Venveis. Wenn die Seite geladen wird, werden sie über die Methode getElementsByID angesprochen und ihr Inhalt durch innerHTMl ersetzt.
Die all·(ollection, inner/outerHTML und inner/outerTelt I 103
Beispiel 9-/4: Zugriffaufbellallllle Elemellte und Ändern des inllerHTML < I OOCTYPE html PUBLIC "-IIW3CIIDTO XHTML 1.0 TransitionalllEN" "http://www.w3.org/TR/xhtmll/0TD/xhtmI1-transitional .dtd"> Elemente nach dem Laden der Seite verändern <script type_"text/javascript"> 11
Absatztext .
- option 1
- option 2
Beispiel 9-1z Beispiel 1
U!ll!ewohniche W.b,eil.
Zun Laden dor s.t.
rnllchn
Arl Drei<Jp> Die Absätze haben keine Bezeichner, um sie einzeln direkt per getElementByld anzuspre chen. Sie können staudessen getElementsByTagName nutzen und das Absatz-Tag über geben: var ps
•
document.getElementsByTagName("p");
Aber so erhalten Sie alle Absätze des Dokuments. Dies kann durchaus von Ihnen gewollt sein, aber wie kommen Sie nur an die beiden Absätze im ersten div-Block? Um die Absätze in diesem neuen Kontext anzusprechen, greifen Sie zunächst per get
ElementByld (oder jede andere Ihnen genehme Methode) auf das div-Element zu: var div
•
document.getElementByld("divl")j
Dann können Sie durch Vererbung aus dem Objekt Element mit getElementsByTagName alle Absätze erhalten: var ps
•
div.getElementsByTagName("p")j
Die einzigen Absätze in der zurückgegebenen NodeList sind die, die im ersten durch divl identifizierten div-Block liegen. Da immer mehr Webseiten für die Nutzung mit CSS entworfen werden, bei denen die Ele mente in ineinander gebetteten Schichten liegen, ist das Arbeiten mit Elementen in einem Kontext eine Möglichkeit, ein wenig die Kontrolle darüber zu behalten, welche Kompo nenten einer Seite von der JavaScript-Anwendung beeinflusst werden. Das ist insbesondere dann von Vorteil, wenn Sie mit diesem Ansatz das Dokument verändern wollen.
Element und Zugriff im Kontelt I 231
Den Baum anpassen Das Dokument ist der Besitzer/das übergeordnete Element aller Seitenelementc. Daher sind die meisten Fabrikmethoden zum Erstellen von Instanzen neuer Elemente Metho den des Corc-Objekts document. Über den Node bewegt man sich allerdings in der Corc AP!. Das hilft bei der hierarchischen Struktur des Dokumentenbaums, in dem jeder Kno ten eine Beziehung zu anderen Knoten hat und die Navigation dieser natürlichen Struk tur folgt: Ehern/Kind, Geschwister/Geschwister. Schließlich bietet Element eine Möglich keit, auf die Elemente innerhalb eines Kontexts zuzugreifen, um Änderungen an eingebetteten Elementen vorzunehmen. Alle drei sind grundlegende Objekte, mit denen man den Dokumentenbaum modifizieren kann. Die Fabrikmethoden von document und der Typ der Core-Objektc, die sie erstellen, sind in Tabelle 10-1 aufgeführt. Hier finden Sie auch eine kurze Vorstellung vieler Core-Objekte.
Tabelle 10-1: FabrikmethodCIl des Objekts documellt Melliode
Erstelltes Objekt
Bes <script type_"text/javascript"> 11 _
Auf der Seite wird eine Instanz von Tune mit dem Object-Konstruktor erzeugt und ein Liedtitel » Hallo,< übergeben. Dann wird die Methode addPerformer dreimal aufgerufen> und drei Interpreten werden hinzugefügt: Ich, Du und Wir. Die Methode listPerformers wird anschließend aufgerufen> damit sie die Interpreten ausgibt. Schließlich wird noch der Liedtitel ausgegeben. Schauen wir uns das noch genauer an: In dem Skript erstelle ich zunächst eine Funktion mit dem gleichen Namen wie das Objekt> Tune. Erinnern Sie sich aus den früheren Kapi teln damn, dass alle Funktionen in JavaScript gleichzeitig auch Objekte sind. Daher erstellen wir durch das Erstellen dieser Funktion tatsächlich unser eigenes Objekt. Innerhalb der Funktion gibt es zwei Eigenschaften und zwei Methoden. In diesem Bei spiel sind die Codeblöcke, die beide Methoden implementieren, als Teil der Objektde klaration eingebettet. Aber man muss es so nicht machen. Eine Reihe von Objekten> die ich über die Jahre verwendet habe, um meine browserübergreifenden DHTML-Aktivitä ten im Griff zu behalten> setzt jede Objekteigenschaft auf eine Methode> die dann außer halb der Funktion zum Konstruieren des Objekts implementiert wird: function someObjeet( ) { this.methodl objMethodl; •
} function objMethodl()
Ein guter Grund für diesen Ansatz ist, dass der Code leichter zu lesen ist. Sie könnten die gleiche Methode auch verschiedenen Objekten zuweisen> aber es ist im Allgemeinen bes ser, eine Form der JavaScript-Vererbung zu nutzen> die als »verkettete Konstruktoren« bekannt ist (und später in diesem Kapitel behandelt wird) . Ein anderer Ansatz zum Erstellen eines eigenen Objekts ist> eine Instanz des Objekts zu erstellen und dann die Prototypeigenschaft des Objekts zu nutzen, um sowohl Eigen schaften als auch Methoden zuzuweisen. Beispiel 1 1-3 zeigt dies mit einer Abwandlung
Enteilen Sie Ihreeigenen JavaSuipt-Obfekte I 241
des Objekts Tune, aber dieses Mal verwende ich einen Prototype, um einer Objektme thode eine Funktion zuzuweisen.
Beispiel J J -3: Eigenschaften und/oder Methoden per Prototype zuweisen < I OOCTYPE html PUBLIC "-IIW3CIIDTO XHTML 1.0 TransitionalllEN" "http://www.W3. org/TR/xhtmll/0TD/xhtmI1-transitional.dtd"> <script type_"text/javascript"> 11 verpacken« - eine effektive Möglichkeit, um mit Browserunterschieden umzugehen.
Der nächste Abschnitt behandelt diese Objektkapselung in JavaSeript, aber auch Objekte in verschiedenen Browsern. Wir werden uns ebenfalls anschauen, wie Sie erkennen kön nen, ob eine bestimmte Funktionalität unterstützt wird oder nicht.
Objekterkennung, Kapselung und browserübergreifende Objekte Mit der Veröffentlichung der CSS und dem Netscape Navigator 4.x sowie dem Internet Explorer 4.x von Microsoft konnten Entwickler von Webseiten endlich komplexe Seiten effekte erstellen, wie zum Beispiel animierte Inhalte, einklappende Menüs und Benach richtigungen direkt auf der Seite. Das einzige Problem lag darin, dass nicht alle Browser dabei das gleiche Objektmodell venvendeten. Eine Möglichkeit, diese Inkompatibilität zwischen den Browsern zu umgehen, war, auf den Agent-String zuzugreifen, um herauszufinden, welcher Browser auf die Seite zugreift, und den JavaScript-Code entsprechend anzupassen. Dieser Ansatz, auch als Browser Stli/ fing bekannt, wurde schnell venvorfen zu Gunsten eines anderen: der Objekterkenmmg.
Objekterkennung, Kapselung und browserübergreifende Objekte I 243
Objekterkennung Bei der Objekterkennung greift JavaScript auf ein zu erkennendes Objekt in einer be dingten Anweisung zu. Wenn das Objekt nicht existiert, wird die Bedingung zu false ausgewertet. In Kapitcl 9 habe ich ein Objekt erwähnt, das häufig in älteren Skripten ge nutzt wird: document.all. Indem man auf document .all prüft, kann man einen Browscr erkennen, der das IE 4.x-Modell unterstützt. Eine andere häufig genutzte Variante ist die Überprüfung von document.layers, das vom Netscape Navigator 4.x unterstützt wird: if (document.layers) . . . Glücklicherweise unterstützen alle modernen Browser ein ziemlich konsistentes Modell. Alle bieten document.getElementByld, das für den Zugriff auf bestimmte Elemente not wendig ist, und alle bieten die Eigenschaft style (die im nächsten Kapitel behandelt wird), mit der man die CSS-Style-Eigenschaften eines Elements ändern kann. Aber auch heute noch gibt es Unterschiede. Obwohl ich die JavaScript-Änderungen von CSS-Eigenschaften erst in Kapitel 12 bespreche, wollen wir uns eine bestimmte Eigen schaft anschauen, die sich beim Internet Explorer von anderen Browsern unterscheidet:
opacity. Die Transparenz eines Elements wird bestimmt durch die Prozentzahl seiner Opazität. Microsoft waren die Ersten, die eine Möglichkeit anboten, die Opazität eines Elements dynamisch anzupassen, wobei ein proprietärer Filter namens Alpha-Filter genutzt wurde. Später erstellte die Mozilla-Gruppe eine Abwandlung des Filters und nannte ihn moz opacity. Zur gleichen Zeit entstand im Rahmen der KHTML-Arbeiten (durch den Safari Browser und den Konquerer unter Linux bekannt) eine Eigenschaft namens
khtml-opa
city. Mit der Veröffentlichung von CSS 3.0 wurde für die Opazität eine universelle Eigen schaft mit dem schlichten Namen opacity definiert. Die Mozilla-Linie der Browser ist zum neuen CSS3-Standard gewechselt, ebenso Safari. Seltsamerweise hat sich Microsoft dazu entschieden, diese Eigenschaft nicht zu unter stützen und weiter mit dem Alpha-Filter zu arbeiten - selbst im neuen IE 7. Daher ist eine Objekterkennung notwendig, um einen Effekt zu erzeugen, der sowohl mit dem IE als auch mit anderen Browsern arbeitet, die die CSS3-Eigenschaft opacity unterstützen. In Beispiel 11-4 wird die Objekterkennunggenutzt, um zu ermitteln, welchem Weg man folgen sollte - dem Alpha-Filter oder dem Setzen der CSS-opacity. Das Ziel ist ein Bild, das in der Seite eingebettet ist. Dessen Opazität wird bei jedem Klick auf die Seite um 10% reduziert. Da der Alpha-Filter von Microsoft einen Prozentwert nutzt und keinen digitalen Wen, wird die Variable mit der aktuellen Opazität mit 100 multipliziert, sobald der lE ins Spiel kommt.
Beispiel 1 1 -4: Mit ObJekterkemlUlIg bestimmell, wie mall die Opazität anpasst < IOOCTYPE html PUBLIC "-/JW3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3. org/TR/xhtmllJDTD/xhtm11-transitional.dtd")
244 I Kapitelll: Eigene Objekte inJavaScript eritellen
Beispiel 1 1 -4: Mit Objekterkenllung bestimmell, wie man die Opazität anpasst (Fortsetzung) <script type_"text/javascript"> 11 <style type-"textJcss"> div { position: absolute;
246 I Kapitel ll: Eigene Objekte inJavaScripl elitelien
Beispiel 11-5: Objektkapselwlg (Fortsetzung) top: 30pxj left : SOPXj <script type_"text/javascript"> 11 Anstatt die Methoden direkt im Objekt zu implementieren, werden sie in diesem Beispiel außerhalb als eigenständige Funktionen codiert. Sie können das vor allem dann machen, wenn Sie browserübergreifende Objekte erzeugen, bei denen alle Versionen der Objekte manche der Methoden verwenden können, wie das hier bei der Funktion getOpacity der Fall ist (die bei jedem Aufruf eine Objekterkennung durchführt) , aber bei denen manche Methoden doch spezifisch sein müssen (wie die beiden Methoden zum Ändern der Opa zität des Objekts, die über Objekterkennung gesetzt werden, wenn das Objekt erzeugt wird). Es macht meiner Meinung nach den Code auch ein bisschen besser lesbar, da Sie jede Funktion dokumentieren und nicht allzu verschachtelt vorgehen müssen. Das Beispiel verwendet zudem parseFloat, um sicherzustellen, dass die Zah len als Zahlen und nicht als Suings angesprochen werden. Später, im Ab schnitt über Ausnahmebehandlung, werde ich zeigen, was passien, wenn Sie diese Funktion nicht verwenden. Die Verwendung von Objekterkennung, eigenen Objekten und Kapselung ist heutzutage nicht mehr so wichtig wie früher, als sich die DHTML-Unterstützung der Browser deut licher unterschied. Aber es ist immer noch eine gute Möglichkeit, Browserunterschiede auszublenden. Zudem unterstützt man damit die alte Philosophie ,)einmal codiert, viel fach genutzt« bei der Anwendungsentwicklung.
248 I Kapitelll: Eigene Objekte inJavaScript eritellen
Beachten Sie die DOM Level 2-Funktionalität von getElementsByTagName, um auf alle div-Elemente zuzugreifen, die dann dem Konstruktor für das eigene Objekt übergeben werden, damit sie alle hübsch verpackt werden. Um Effekte zu erzeugen, die die gesamte Seite betreffen, ist es hilfreich, die Seitenelemente in div-Elementen zu verpacken und dann jedes als eigenes Objekt zu kapseln. Dadurch vereinfacht man die Entwicklung auf wendigerer Funktionen. Wir werden uns dies noch genauer in den nächsten zwei Kapitel anschauen.
Ändern von Konstruktoren und die Vererbung in JavaScript JavaScript ist keine typische OO-Sprache und sollte auch nicht dorthin gedrängt oder genötigt werden. Sie hat ihre eigenen Stärken, die man zu seinem Vorteil nutzen sollte. Aber es gibt Elemente klassischen objektorientierten Designs, die man in Anwendungen gut gebrauchen kann. Im letzten Abschnitt haben wir eine Form von OO-basiertem Design kennengelernt: Kapselung. Dieser Abschnitt behandelt eine andere Form: Vererbung.
Vererbung übernimmt (oder erbt) die Methoden und Eigenschaften eines anderen Ob jekts in ein neues Objekt. Das ist die Grundlage der Mächtigkeit klassenorientierter Ent wicklung, weil eine Klasse von einer anderen erben kann und dabei entscheidet, welche Funktionen überschrieben werden, um in der neuen Klasse ein anderes Verhalten zu er reichen. Man kann in JS etwas Ähnliches machen, um dieses Verhalten zu emulieren. Das ist seit JavaScript 1.3 möglich - mit den Funktionsmethoden apply und (all. Zurück zum vorigen Beispiel: Wenn eine Funktion geschrieben wird, die ein neues Ob jekt definiert, wird diese zum Objektkonstruktur und wird aufgerufen, wenn das Schlüs selwort new zusammen mit der Funktion erscheint: theobj
•
new OivObj(params);
Sowohl die Methode apply als auch (all ermöglichen es Ihnen, eine Methode innerhalb des Kontexts eines anderen Objekts aufzurufen. Wenn man sie in einem Objektkon struktor aufruft, verketten sie die Konstruktoren so, dass alle Eigenschaften und Metho den des einen Objekts vom eigenen Objekt geerbt werden. Der einzige Unterschied zwi schen den beiden Methoden liegt in den übergebenen Parametern - das Verhalten ist gleich. Die Methode (all erwartet das abgeleitete Objekt als ersten Parameter, das durch this übergeben wird, und dann alle Argumente, die Sie dem Konstruktor des Objekts übergeben wollen: obj . cal1(this ,argl, argl, . . . , argn); Die Methode apply dagegen erwartet eine Referenz auf das abgeleitete Objekt und das Array mit den Argumenten des Containers. Wenn das Objekt zwei Parameter hat und der Container drei, werden nur die ersten beiden Argumente des Arrays an das »alte'< Objekt übergeben: obj.apply(this,arguments);
Ändern von Konstruktoren und die Vererbung in JavaSc:ript I 249
Verwenden Sie gemeinsame Argumente, nutzen Sie apply, ansonsten call. Beispiel 11-6 nutzt apply und verkettete Konstruktoren, um Vererbung zu zeigen. Das erste erzeugte Objekt tune speichert Informationen über einen Liedtitel und die An der Musik. Es hat zudem eine Methode, die einen String mit diesen beiden Informationen zurückliefen. Das zweite Objekt artist_tune besitzt auch eine Eigenschaft für den Künst ler und eine Funktion, um einen String mit allen Eigenschaften zu erstellen. Die Methode apply wird direkt für die Funktion/das Objekt tune aufgerufen. Zudem wird nach der Definition beider Objekte der Prototype von artist_tune dem Konstruktor von tune zuge wiesen.
Beispiel J J ·6: Verkettete KOllstruktorell wld Vererbwlg über die Methode apply < I OOCTYPE html PUBLIC "-IIW3CIIDTD XHTML 1.0 TransitionalllEN" "http://www.W3. org/TR/xhtmll/DTD/xhtmI1-transitional .dtd"> <script type_"text/javascript"> 11 <style type-"text/css"> #div1 { background.color: #ffo } <script type_"text/javascript"> 11
Oies ist ein div-Element
<script type_"text/javascript"> 11 ' p' Mach es grö&er Mach e s kleiner ' p' •
270 I Kapitel 12: Dynamisc:he Webseiten erstellen: Stylen Sie IhrSkript
Beispiel 12-3: Einen Textblock anpassen (Fortsetzung) Eines der ersten präsentationsspezifischen HTHl-Elemente war font, es ist auch eines der ältesten HTHl-Elemente, die Sie immer noch viel zu häufig auf Webseiten finden. Es ist nicht überraschend, dass font- und text-Eigenschaften beim Bauen von Webseiten von solchem Interesse waren. Nur wenige Änderungen, die Sie an den Style-Attributen eines Elements vornehmen, können zu solchen Effekten führen wie Änderungen an text oder font . Beachten Sie, dass ich von den Eigenschaften text oder font rede. font hat etwas mit den Zeichen selbst zu tun: der Schriftfamilie, dem Typ und anderen Elementen der Zeichenerscheinung. Die text-Attribute haben dagegen mehr mit dem Drumherum beim Text zu tun: der Ausrichtung, verzierung und so weiter.
Sie werden den Text vermutlich nicht so sehr vergrößern, wie ich es in diesem Beispiel getan habe, aber es zeigt, was für Umwandlungen Sie mit JavaScript und CSS erreichen können. Eine andere typische Anwendung ist das Ändern der Schriftfarbe eines Text felds, das mit einem form-Element oder einem Textblock verbunden ist, um zu zeigen, dass es nicht nutzbar ist - die Schriftart wird wortwörtlich ,)ausgegraut".
Position und Bewegung Wenn Sie im Zeitalter vor CSS das Layout der Seite halbwegs im Griff behalten wollten, mussten Sie eine HTML-Tabelle verwenden. Und für jegliche Form von Animation gab es entweder animierte GIFs oder ein Plug-in wie Flash. Netscape und Microsoft machten dem gemeinsam ein Ende, indem sie eine Spezifikation
namens CSS-P bzw. CSS Positioning vorstellten. Stellen Sie sich die Seite als einen Gra phen mit x- und y-Koordinaten vor. Mit CSS-P können Sie die Position eines Elements innerhalb dieses Koordinatensystems setzen. Und mit etwas JavaScript-Code lassen sich Elemente auch auf der Seite verschieben. Die vorgeschlagenen CSS-P-Attribute wurden schließlich in die CSS2-Spezifikation über nommen. Zu den Positionierungseigenschaften in CSS2 gehören:
position Die Eigenschaft position enthält einen von fünf möglichen Werten: relative, ab solute, static, inherit oder fixed. Positionierung per static ist die Standardeinstel lung für die meisten Elemente. Das bedeutet, dass sie im Seitenlluss mitlaufen, andere Elemente auf der Seite die Position des Elements beeinllussen und das Ele ment selbst auf die Position der folgenden Elemente einwirkt. relative ist gleich, nur wird das Objekt von seiner normalen Position ausgehend verschoben_ Eine absolute Position nimmt das Element aus dem Seitenlluss heraus und ermöglicht es Ihnen, seine Position auf der Seite absolut zu setzen_ Sie können Elemente auch überein ander positionieren, indem Sie ihnen die gleiche Position mitgeben_ Eine Position mit fixed gleicht der absoluten Positionierung, nur dass das Element relativ zu einem
Position und Bewegung I 271
Viewport positioniert wird. Für die meisten DHTML-Arbeiten werden Sie absolute oder relative verwenden.
top Im Koordinatensystem der Webseite beginnt der Wert von x oben und ist dort null. Er wächst, während Sie sich im Container abwärts bewegen, egal ob der Container die Seite oder ein anderes Element ist. Indem Sie die Eigenschaft top setzen, geben Sie die Position relativ zum oberen Rand des Containers an.
left Im Koordinatensystem der Webseite beginnt der Wert von y auf der linken Seite und ist null. Auf dem Weg im Container nach rechts erhöht sich der Wert. Indem Sie die Eigenschaft left setzen, definieren Sie die Position relativ zur linken Seite des Con tainers.
bottom Die Eigenschaft bottom steht beim Wert null für das untere Ende der Seite. Größere Werte verschieben das Element auf der Seite nach oben.
right Die Eigenschaft right hat am rechten Rand einer Seite den Wert null. Größere Werte verschieben das Element nach links.
z- index Vielleicht werden Sie auch den z-index verwenden wollen. Wenn Sie auf der Seite eine senkrechte Linie ziehen, ist das der z-Indcx. Wie schon bei der absoluten Posi tionierung erwähnt, können Elemente übereinander positioniert werden. Die Posi tion innerhalb dieses Stapels wird durch zwei Dinge kontrolliert: Zunächst ist die
Position auf der Seite entscheidend. Elemente, die später definiert wurden, liegen im Stapel höher, am Anfang definierte Elemente weiter unten. Das lässt sich mit z-index überschreiben. Sowohl negative als auch positive Integer-Zahlen können genutzt werden, wobei 0 dem normalen Rendering-Layer entspricht (relative Positionie rung), negative Zahlen verschieben ein Element nach hinten, positive nach vorne. Das Attribut display beeinllusst ebenfalls Positionierung und Layout, aber es wird erst später im Abschnitt ,)Anzeige, Sichtbarkeit und Opazität" behandelt. Das Attribut float ist auch mit in die Positionierung involviert, aber es arbeitet nicht gut mit DHTML zu sammen, daher werde ich es hier nicht behandeln. Die Eigenschaften top, right, bottom und left, aber auch z- index, sind nur dann wirk sam, wenn position auf absolute gesetzt wird. Elemente können »außerhalb" der Seite gesetzt werden, indem Sie eine der Eigenschaften auf einen negativen Wert setzen. Ele mente lassen sich auch in Abhängigkeit von Events verschieben, zum Beispiel bei einem Mausklick. Ein beispielhafter DHTML-Effekt ist das Fly-in, bei dem Elemente von den Seiten des Dokuments hereinzulliegen scheinen. Es ist eine guter Effekt für Tutorien oder andere
272
I Kapitel 12: Dynamisc:he Webseiten erstellen: Stylen Sie IhrSkript
Aufzählungen, bei denen Sie ein Thema nach dem anderen vorstellen und dabei einen Mausklick oder einen Tastendruck als Auslöser nutzen wollen. Beispiel 12-4 zeigt ein Fly-in mit drei Elementen, die aus der oberen linken Ecke kom men. Ein Timer hilft beim Ausführen der Bewegung und wird immer wieder zurück gesetzt, bis der obere Wert x größer als ein bestimmter Wert ist (100 + ein Wert x der Anzahl der Elemente, um eine Überlappung herzustellen) . Die Elemente werden bei der initialen Positionierung auf der Seite links oben außerhalb verborgen, da man durch das Setzen von Elementen weit rechts oder unten nur einen Scrollbalken hervorzaubert.
Beispiel 12-4: Positiollierung li011 Elementen und Bewegwlg dlnch Fly-ills < ! DQCTYPE html PUBLIC "-IIW3CIIDTD XHTML 1.0 TransitionalllEN" "http://www.�3. org/TR/xhtmll/DTD/xhtmll-transitional.dtd"> <style type·"text/css"> div { padding: 10pxj } #divl { background-color: #oofj color: #fff; font-size: largerj position : absolutej width: 400pxj height : 100pxj left: -410pxj top: -400pxj } #div1 { background-color: #ffOj color: #j font-size: largerj position : absolutej width: 400pxj height : 100pxj left : -410pxj top: -400pxj } #div3 { background-color: #fOOj color: #fff; font-size: largerj position : absolutej width: 400pxj height : 100pxj left : -410pxj top: -400pxj } <script type_"text/javascript"> lId [CDATA[
Position und Bewegung I 273
Beispiel 12-4: Positiolliefllllg VOll ElemelltCII Ulld Beweglmg dlnch Fly-ills (Fortsetzullg) var element . ["div1", "div2" , "div3 " ) j function next ( ) { setTimeout( "moveBlock()",l000); var x · Oj var y · Oj var e1em O j function moveBloc k ( ) X+_20j y+-20j var obj document .getElementById(element[elem) ) j obj.style.top x + "px"j obj.style .left y + "px"; if (x < (100 + eIem * 60» { setTimeout("moveBlock( ) " , 100) j } else { eIem++j x · Oj y · Oj •
•
•
•
} JJ))> <Jscript> <Jhead> ' p' Nächste Seite Franz jagt im komplett verwahrlosten Taxi quer durch Bayern. Eisgekühlter Bommerlunder, Bommerlunder eisgekühlt, eisgekühlter Bommerlunder, Bommerlunder eisgekühlt .
Ein belegtes Brot mit Schinken, ein belegtes Brot mit Ei, web 1.0 WEB 2 . 0 weB 2222 . . . . 0000
Ich bin so cool, Der Text in den Beispielen ist recht sinnfrei, aber mit ein bisschen aufgehübschtem Design und sinnvolleren Inhalten ist das eine effektive Präsentationstechnik. Abbildung 12-2 zeigt ein Bildschirmfoto der Seite, geöffnet in Firefox.
274 I Kapitel 12: Dynamisc:he Webseiten erstellen: Stylen Sie IhrSkript
Abbildung 12-2: Fly-in-Seite Um die Seite barrierefreier zu machen, kann die Verknüpfung so geändert werden, dass Seiten mit den '>einfliegenden« Informationen geöffnet werden. Alternativ können auch alle drei Informationsblöcke auf der Seite positioniert und per Skript versteckt werden, wenn JavaScript aktiv ist. Eine andere recht häufig genutzte Anwendung von DHTML im Zusammenhang mit Bewegung hat viel mit dem Verfolgen der Bewegung des Benutzers zu tun, wenn er Ele mente auf der Seite anfasst. Die Technik wird als Drag-and-Drop bezeichnet und im nächsten Abschnitt behandelt.
Drag-and-Drop Ein DHTML-Thema, das bei seiner ersten Vorstellung großes Interesse geweckt hat, ist Drag-and-Drop. Es tauchten an allen Ecken und Enden Beispiele für Einkaufswagen auf, auch von mir war die eine oder andere Version dabei. Ich hatte sogar ein Drag-and Drop-Spiel erstellt. Mit der Zeit haben wir aber festgestellt, dass sich Drag-and-Drop in den echten Anwen dungen kaum verbreitete. Ich finde selten eine echte Anwendung, die Drag-and-Drop nutzt, und wenn, bin ich irritiert. Warum? Es ist nicht immer leicht, Drag-and-Drop
Position und Bewegung I 275
durchzuführen, insbesondere wenn Sie ein Trackpad oder einen sprachgesteuerten Brow ser verwenden. Wiederenveckt hat das Interesse an Drag-and-Drop Google Maps. Dort können Sie eine Karte in einem begrenzten Bereich verschieben. Es war das erste Mal, dass ich eine wirk lich effektive Anwendung von Drag-and-Drop gesehen haben. Wir werden uns Google Maps und die zugehörige API in Kapitel 13 anschauen, aber hier wollen wir uns unsere eigene, sehr kleine Emulation der Drag-and-Drop-Technologie anschauen. Bei Google Maps ist es besonders beeindruckend, dass die Anwendung beim Scrollen durch eine Karte immer schon gleich die nächsten Kartenkacheln vom Server lädt und über einen Caching-Mechanismus in die Seite integriert. Damit sieht es so aus, als würden Sie nie das Ende der Karte erreichen. Wirklich ein feines Stück Arbeit. In Beispiel 12-5 wird ein div-Element erstellt und ein Bildschirmfoto aus dem Buch im Element eingebettet. Zusätzlich zu Drag-and-Drop wird auch das Attribut overflow ver wendet. Sie werden über overflow später noch mehr erfahren. Hier ist das div-Element so eingestellt, dass der überstehende Inhalt verborgen oder abgeschnitten wird. Damit wird vermieden, dass das Bild übersteht.
Beispiel 12-5: Der Google Maps-Effekt: ein Objekt in einem Conrainer per Drag-attd-Drop verschieben < I OOCTYPE html PUBLIC "-IIW3CIIDTO XHTML 1.0 TransitionalllEN" "http://www.W3. org/TR/xhtmll/0TD/xhtmll-transitional .dtd"> <style type·"text/css"> #divl { overflow: hidden; position : absolute; top: 100px; left : l00px; border: Spx solid #000; width: 400px; height : 200px; } img { border: lpx solid #000; } <script type."text/javascript"> 11 <Jscript> <Jhead> Das ist das komplexeste Beispiel, das wir bisher im Buch hatten, daher wollen wir uns den Code näher anschauen:
• Es werden zwei globale Objekte erzeugt: dragObject und mouseOffset. Das erste ist das zu ziehende Objekt, das zweite der Offsetwert des Objekts. Der Offset ist die Position des Objekts relativ zu einem Container (in diesem Fall einer Seite) _ Wir fangen auch die Events mousemove und mouseup für das Dokument ab und weisen sie den Event-Handlern mouseMove und mouseUp zu_
• Das nächste ist ein Objekt: mousePoint. Damit werden nur die beiden Mauskoordi naten x und y gekapselt. Durch solch ein Objekt ist es einfacher, beide Variablen weiterzugeben.
• Die nächste Funktion ist mousePosition_ Diese Funktion greift auf die Werte clientX und clientY des Zielobjekts zu und liefert ein Objekt vom Typ mousePoint zurück, in dem die x- und die y-Position des Objekts relativ zum Clientbereich des Fensters zu finden sind - abzüglich der ,)Verzierungen«. Die Funktion parseInt stellt sicher, dass die Werte als Zahlen zurückgegeben werden.
• Dann folgt getMouseOffset, das als Parameter ein Objektziel und ein event envartet. Nachdem das event-Objekt an die Unterschiede zwischen den Browsern angepasst wurde, wird die Mausposition des Events an die eben besprochene Funktion mouse Point übergeben. Dieses wird dann bezüglich der Eigenschaften offsetLeft und offsetTop angepasst. Wenn wir das nicht tun, würde das Objekt zwar mit der Maus verschoben werden, aber es gäbe eine sehr ruckartige Bewegung, und das Objekt würde über, unter oder neben der Maus liegen. Durch die Normalisierung wird ein normalisierter mousePoint erzeugt, der dann zurückgegeben wird.
• Die nächste Funktion ist mouseUp, die nur das Ziehen ausschaltet, indem dragObject auf null gesetzt wird. Dann kommt die Funktion mouseMove, in der der Großteil der
278 I Kapitel 12: Dynamisc:he Webseiten erstellen: Stylen Sie IhrSkript
Zug-Berechnungen durchgeführt wird. Die Funktion wird verlassen, wenn das zu ziehende Objekt nicht gesetzt ist. Wenn doch, wird die normalisierte Mausposition ermittelt, das Objekt auf absolute Positionierung gesetzt, und seine Eigenschaften left und top werden gesetzt (wieder angepasst durch den Offset).
• Die letzte Funktion ist makeDraggable, die das der Funktion übergebene Objekt in ein ziehbares verwandelt. Das geschieht, indem für das Objekt das Event mousedown einer Funktion zugewiesen und der Offsetwert bestimmt wird. Das sieht nach einer Menge Code aus, ist aber tatsächlich viel einfacher als früher bei den älteren Browsern, weil die meisten modernen Browser die gleichen Eigenschaften beim Positionieren nutzen. Zum Glück, denn Drag-and-Drop ist auch ohne zusätzliche Her ausforderungen schwierig genug. Auch hier ist Google Maps Vorreiter, indem es die Karte per Ajax kontinuierlich aktualisiert, so dass Sie niemals an ihren Rand gelangen. Das geht allerdings ein wenig über den Rahmen dieses Buchs hinaus. Sehen Sie es einfach als zukünftige persönliche Herausforderung an.
Größe und Clipping Die Größe eines Elements wird über sechs CSS-Attribute beeinllusst. Die ersten beiden,
width und height, sind die gebräuchlichsten und werden genutzt, um die absolute Breite und Höhe des Elements zu definieren. Die anderen vier - min-height, min-width, max height, max-width - sind nützliche CSS-Attribute (insbesondere bei der Arbeit mit Bil dern), aber bei dynamischen Effekten nur selten im Einsatz. Tatsächlich sind Breite und Höhe eines Elements FaktOren verschiedener Attribute. Dazu gehören border, margin, padding und content des Elements. Kombiniert man alle miteinander, erhält man ein CSS-»Boxmodell«, das mit Blockelementen verbunden ist - also Elementen, die davor und danach einen Zeilenumbruch haben. Lesen Sie zum Boxmodell mehr auf der W3C-Seite »Box Model« unter hllp://www.w3.orgrrRlREC-CSS2/box./um. Wenn die Inhalte eines Elements für das Element zu groß sind, wird das Verhalten be züglich des überstehenden Inhalts über das CSS-Attribut overflow geregelt. Dieses kann auf visible (den gesamten Inhalt rendern und die Grenzen des Elements überschreiten), hidden (den Inhalt abschneiden), seroll (den Inhalt beschneiden und Scrollbalken an bieten) und auto (den Inhalt beschneiden, Scrollbalken nur dann anbieten, wenn ein Teil des Inhalts verborgen ist) gesetzt werden. Warum sollte man die Höhe eines Elements setzen? Wenn die Höhe nicht defi niert wird und overflow nicht auf clip steht, wird das Element automatisch so angepasst, dass der Inhalt hineinpasst. Haben Sie Inhalte in zwei Spalten, die nebeneinanderliegen, wollen Sie viel leicht die Höhe der Spalten angeben, damit eine nicht wesentlich länger ist als die andere.
Größe und (Iipping I 279
Overflow und dynamischer Inhalt Wenn der Inhalt eines Elements dynamisch ersetzt wird, sei es durch einen Ajax-Aufruf oder ein anderes Event, kann es sein, dass der Inhalt im Verhältnis zur Größe des Ele ments völlig andere Dimensionen hat. Eine Möglichkeit, um sicherzustellen, dass der Inhalt immer vollständig erreichbar ist, liegt in der Verwendung von auto. Wenn der Inhalt zu groß ist, werden Scrollbalkcn angezeigt. [n Beispiel 12-6 gibt es zwei Blöcke: einen mit sehr viel Text und einen mit wenig Text. Die Dimensionen beider Elemente werden beim Laden der Seite so gesetzt, dass der Inhalt sicher hineinpasst. Aber es gibt eine Vcrknüpfung, die den Inhalt austauscht: wenig nach viel und viel nach wenig. 1m CSS ist der Overtlow für das zweite Element auf auto gesetzt.
Beispiel 12-6: Andem des Inhalts und die AuswirkungeIl der O�'erflow-Eillstellung < I OOCTYPE html PUBLIC "-IIW3CIIDTO XHTML 1.0 TransitionalllEN" "http://www.w3.org/TR/xhtmll/0TD/xhtmll-transitional .dtd"> <meta http-equiv_"Content_Type" content_"text/htmlj charset_utf_B" I> <style type-"text/css"> #divl { width: 700pxj height : 150px } #div1 { width: 600pxj height : l00pxj overflow: auto } <script type_"text/javascript"> 11 ' p' wechseln ' p' Eines der ersten präsentationsspezifischen HTMl-Elemente war font, und es ist auch eines der ältesten HTML-Elemente, die Sie immer noch viel zu häufig auf Webseiten finden. Es ist nicht überraschend, dass font- und text-Eigenschaften beim Bauen von Webseiten von solchem Interesse waren. Nur wenige Änderungen, die Sie an den Style-Attributen eines Elements vornehmen, können zu solchen Effekten führen wie Änderungen an text oder font.
280 I Kapitel 12: Dynamisc:he Webseiten erstellen: Stylen Sie IhrSkript
Beispiel 12-6: Ändert! des lllhalts und die Auswirbmgm der Overflow-Eillstellung (FortsetZ!IIIg) ' p' Beachten Sie, dass ich von den Eigenschaften text oder fant rede. font hat etwas mit den Zeichen selbst zu tun: der Schriftfamilie, dem Typ und anderen Elementen der Zeichenerscheinung . Die text-Attribute haben dagegen mehr mit dem Drumherum beim Text zu tun: der Ausrichtung, verzierung und so weiter. Element Eins
Element Zwei Dies ist die Hilfe für das erste Element . Sie ist nur Zu sehen, wenn Sie auf die Beschreibung des Elements klicken. Dies ist die Hilfe für das zweite Element. Sie ist nur zu sehen, wenn Sie auf die Beschreibung des Elements klicken. Ich habe noch ein CSS-Sahnehäubchen draufgesetzt, damit es besser schmeckt. Das For mular wird mit einem farbigen Hintergrund gerendert, der Hilfeblock erhält einen roten Rahmen, und wenn sich der Mauscursor über die Beschreibung eines Element bewegt, wird der Cursor zu einem Hilfe-lcon, was meist ein Pfeil mit einem kleinen Fragezeichen ist (manchmal auch ohne Pfeil) . Das ist ein sehr einfacher Weg, dem Anwender einen Hin weis zu geben - ähnlich signalisiert das alt-Tag, dass es hier Hilfe gibt. Abbildung 12-3 zeigt dieses verborgene Hilfesystem.
Die: ist cl>: M, fu; Ja< "",,,,, Ebnen!. Si, ct
<E:=·_·_·=_·_·-=;-2=-:;;;=;;=�
oor '" ,.b <style type-"text/css"> .label { background-color: #003; width: 400px; border-right : lpx solid #fff; padding: 10px; margin: 0 lOpx; color : #fff; text-align : center; border·bottom: lpx solid #fff;}
288 I Kapitel 12: Dynamisc:he Webseiten erstellen: Stylen Sie IhrSkript
Beispiel l2-9: Eill eillklappbares Formular implememierell (Fortsetzung) .label a { color: #fff } .elements { background-color: #CC09FF; margin : 0 lOpxj padding: 10pxj width: 400px; display: none} <script type_"text/javascript"> 11 < a href_"#narne" onclick_"return false">Narne Vornarne:
Nachname :
Adresse $tra&e:
Ort:
land :
Andere Oaten oder Informationen.
Anzeige, Sichtbitrkeit und Op.azität
189
Auch dies ist wieder etwas, das man seiner Webseite gern hinzufügt. Es ist einfach, sieht beeindruckend aus und lässt sich auch mit JavaScript-freien Alternativen recht leicht nutzen, wenn JavaScript abgeschaltet ist. Ich habe nur etwas an der Obertläche dessen gekratzt, was Sie mit JavaScript und CSS erreichen können. Hoffentlich gibt es Ihnen aber eine gute Ausgangsbasis. Kapitel 13 führt Sie in die Grundlagen von Ajax ein, dann werden wir Ajax und DHTML kombinie ren, um mächtige Anwendungen zu bauen.
Fragen I . Sie greifen auf die Textfarbe eines Elements in JavaScript mit obj .style. color zu, es wird aber kein Wert zurückgegeben. Sie wissen, dass der Wert in einem Stylesheet gesetzt wurde. Warum wird kein Wert zurückgegeben, und wie würden Sie die Anwendung ändern, damit Sie einen Wert erhalten? 2. Wie würden Sie bei Text in einem div-Block die Schriftart auf 14 Punkt setzen, rote Farbe venvenden und eine Zeilenhöhe von 16 Punkt angeben? 3. Sollte die obere Änderung nicht funktionieren, was könnte der Grund dafür sein? 4. Welche zwei Wege gibt es, um einen Block verschwinden zu lassen? 5. Wenn Drag-and-Drop keine effektive Einkaufswagentechnik ist - welcher DHTML Effekt wäre dann für diese Art von Service nützlich? Die Antworten finden sich im Anhang.
290 I Kapitel 12: Dynamisc:he Webseiten erstellen: Stylen Sie IhrSkript
KAPITEL 1 3
Raus aus der Seite mit Ajax
Manche meinen, es sei das nächste, bessere Web. Andere sehen es eher als Hypc an. Was auch immer man glaubt - Ajax oder AJAX (Asynchronous JavaScript And XML), wie es manche bevorzugen, hat zu einem größeren Interesse an JavaScript im Allgemeinen und dynamischer JavaScript-Funktionalität im Besonderen geführt. Obwohl das Interesse erst in jüngster Zeit so gewachsen ist, ist doch keine der mit Ajax verbundenen Technologien wirklich neu. Ajax basiert auf JavaSeript, das es seit Mitte der 90er-Jahre gibt. Dazu kommen das Document Objcct Model, Standard-Wcbtechnolo gien wie CSS, XHTML und XML, und das Objekt XMLHttpRequest - alles schon seit Jah ren vorhanden.
Neu ist der Umstand, dass ein Konzept für einen Entwicklungstyp eingeführt wurde, das auf neuere Browser traf, die die notwendige Funktionalität bereitstellen. Mit anderen Worten: Die Zeit war reif für die Technologie. Es brauchte nur jemanden, der das merkte, sie zusammenstellte und seine Verwendung bekannt machte. Dieser Jemand war JesseJames Garren mit seiner Veröffentlichung ,)Ajax: A New Approach to Web Appli cations" (http://www.adaptivepath.com/plIblications/essays/archives/000385.php) . Die Ajax-Beispiele in diesem Kapitel unterscheiden sich von den Beispielen aus den anderen Kapiteln darin, dass Ajax eine Serverkomponente erfordert. Ruby ist dabei sehr beliebt, aber jede serverseitige Sprache, die mit den speziellen Ajax-Anfragen umgehen kann, funktioniert. Die Beispiele in diesem Kapitel nutzen PHP, vor allem deshalb, weil sie von allen Sprachen JavaScript am ähnlichsten ist und weil es sich um eine der verbrei tetsten Serverskriptsprachen handelt. In Kapitel 14 werden wir einen Blick auf Ruby und Ajax-Bibliotheken werfen.
1 291
AJAX? Oder Ajax? Als Garren das Konzept vorstellte, nannte er es Ajax. Wenn Ajax aber ein Akronym s i t, sollte es AJAX lauten. Oder vielleicht genauer AJaX. Wie auch immer, Garren nutzte den Begriff als Spitznamen, nicht als Akronym - erst später wurde er dazu, als man versuchte herauszubekommen, wie der Name zu Stande kam. Es
gibt keine richtige oder falsche Wahl - schließlich ist es nur ein Begriff -, und da am häufigsten Ajax genutzt wird, werde ich das auch im Rest des Buchs tun. Außerdem ist es einfacher, als die ganze Zeit die Umschalt-Taste beim Tippen des WOrtS gedrückt zu halten.
Ajax: Nicht nur Code Ajax bedeutet wirklich einen Riesenschritt nach vorn, insbesondere dann, wenn Sie die Funktionalität wirklich brauchen. Sie werden sehen, was ich meine, wenn Sie Ihre Web seite das erste Mal direkt validieren. Wenn Sie auf einen Button klicken können, um ein großes Formular einzuklappen und damit die Seite übersichtlicher zu bekommen, wer den Sie davon überzeugt sein, dass Ajax der einzig wahre Weg ist. Na ja, ja und nein. Ajax hat, wie andere JavaScript-Anwendungen, seine Vor- und Nach teile.
Permawas? Wenn Sie möchten, können Sie eine gesamte Website auf einer Seite erstellen. Dabei nutzen Sie Ajax und andere JavaScript-Techniken und ersetzen in Abhängigkeit von den Aktivitäten des Benutzers Inhalte auf der Seite. Es wird dabei nur zunehmend schwieri ger, eine bestimmte Anzeige des Inhalts wiederherzustellen. Ajax erzeugt wie jede DHTML-Funktionalität keine permanenten Effekte. Sie müssen bei jedem Laden der Seite oder bei jeder Wiederholung von Schritten wiederhergestellt werden und sind vermutlich nicht im Quelltext verfügbar oder ausdruckbar. Es gibt keinen permanenten Verweis (Permalink) auf einzelne Teile, und Ihre Anwender werden auch keinen Verlauf ihrer Aktivitäten sehen können. Am schlimmsten aber ist, dass Ihre Anwender beim Betätigen des Zurück-Buttons nicht innerhalb der Ajax-/DHTML-Anzeige zurückwandern, sondern eventuell ganz die Seite verlassen. Es gibt ganze Frameworks, die sich mit diesem Problem befassen und die zum Beispiel ein Anker-Tag in eine Abfolge von Ajax- oder DHTML-Aufrufen umwandeln. Bevor Sie sich aber damit beschäftigen, sollten Sie sich erst einmal fragen, ob diese Fähigkeit für Ihre Arbeit unbedingt notwendig ist. Auch hier gilt wieder: Wenn Ajax und DHTML dazu dienen, bei anderen, eher klassischeren Funktionen zu helfen, kann es gut sein, dass Sie keine großen Bibliotheken hinzufügen müssen, sondern die schon existierenden
292
I Kapitel n: Raus aus derSeite mitAjax
Technologien benutzen können. Wenn zum Beispiel Ajax und DHTML dazu genutzt werden, ein Formular beim Ausfüllen dynamisch zu validieren, sollte ein Lesezeichen für die Formularseite ausreichen.
'"§
Eine der ersten und häufigsten Anwendungen von JavaScript war das Erstellen von Menüs. Das ist witzig und furchtbarzugleich, denn ein Aspekt Ihrer Site, der vollständig barrierefrei sein sollte - egal für wen oder über welchen Browser -, ist die Navigation. Navigation über JavaScript macht die meisten Tools zur Bar rierefreiheit nutzlos. Eine der besten Seiten zu Ajax und Barrierefreiheit ist WebAlM (Web Acces sibility in Mind) unter http://www.webaim.orglteclllliqueslajaxl. Neben der Behandlung dieser Themen gibt es auch Verweise auf andere Sites, die zusätz liche Informationen bereitstellen.
Sicherheit und Workarounds Einer der Gründe für die schnell gestiegene Popularität von Ajax ist dessen relativ sichere Nutzung - so sicher wie die meisten Webanwendungen (mit den gleichen Sicherungs maßnahmen) . Der Grund für seine Sicherheit ist die JavaScript-Sandbox und deren Ein tluss auf XMLHttpRequest. In den Beispielen befindet sich die Serverseite auf dem gleichen Server und der gleichen Domäne wie die Seite, die die Anfragen an den Server stellt. Wenn ich versucht hätte, diesen Server in eine andere Domäne zu bewegen, hätte ich einen Fehler erhalten. Warum? Weil Ajax die JavaScript-Richtlinie zur gleichen Quelle/Domäne nutzt: Sie können nur Services auf dem gleichen Server (der gleichen Domäne) wie dem der Web seite nutzen. Der Internet Explorer hat eine Einstellung, die Anfragen an andere Domänen erlaubt, aber andere Browser bieten das nicht. Firefox unterstützt digital signierte Skripten und domänenübergreifende Funktionen, aber auch hier sind andere Browser aus dem Spiel. Das bedeutet, dass Sie entweder den Seitenzugriff auf eine bestimmte Domäne beschrän ken oder einen Workaround finden müssen. Eine Möglichkeit ist die Verwendung eines Proxys. Wenn auf dem Webserver ein Proxy installiert ist, können alle Anfragen an den Service über den Proxy laufen, der sie dann entsprechend weiterleitet. Andere Webservices, wie zum Beispiel Google und Yahoo!, codieren die Webservice Anfrage im Skript-Tag, anstatt XMlHttpRequest zu verwenden. Zusätzlich können Sie Ihren Webserver die Anfrage umschreiben und an einen anderen Rechner weiterreichen lassen. Beim Apache brauchen Sie dazu modJewrite, andere Server benötigen andere Services, aber die meisten Sites unterstützen diese Funktion.
Ajax: Nicht nur Code I 293
Ajax Best Praetices Neben den üblichen Ratschlägen zu DHTML zum Reinigen der Daten, die in Anwen dungen ankommen, gibt es eigentlich nur eine spezifische Best Practice für Ajax: nutzen Sie es dann, wenn es sinnvoll ist. Ich bin von Ajax wirklich angetan, weil ich denke, dass man damit noch auf der Seite For mulareingaben überprüfen sowie Listen und Drop-clown-Felder bcfüllcn kann. Aber ich nutze es nicht für alle meine Anwendungen. Probleme mit der Barrierefreiheit, fehlende Pcrmalinks und der nicht vorhandene Verlauf sind gute Gründe, warum ich das nicht tue. Dazu gibt es viele andere Anwendungskomponenten, die aktuell verwendet werden - sie sind stabil, einfach zu implementieren und sollten auch weiter genutzt werden. $0 würde ich zum Beispiel nicht empfehlen, mit Ajax Datensätze aus einer Datenbank auszulesen und damit eine Tabelle aufzubauen. Warum? Weil die Verwendung der Ser veranwendung zum Erzeugen einer Datentabelle (entweder über die Ausgabe der Werte oder durch ein Template-System) einfacher und schneller vonstatten geht. Die Seite kann üblicherweise mit einem Lesezeichen versehen werden, und die Anfrage lässt sich im Verlauf speichern. Mit Ausnahme des Einsatzes der neuesten Modetechnik bietet Ajax bei dieser Art von Funktionalität nicht sehr viel. Aber Ajax ist wunderbar, wenn es um das Überprüfen einer Anmeldung oder anderer Formularinhahe geht, da Sie dann nicht alles verlieren, was Sie schon eingegeben haben. Und was die Verwendung von Ajax zum Erstellen des ultimativen Schreibprogramms angeht: Ich habe schon einen tollen Editor. NeoOffice ist das Mac-Frontcnd für Open Office. Ich brauche keine browserbasierte Alternative, und die meisten anderen auch nicht. Wenn ich meinen Online-Weblog-Editor nutze, mag ich allerdings durchaus einige der Ajax-Features - so kann ich zum Beispiel Kategorien beim Klicken auf eine Toolbar auswählen. Mit anderen Worten: Ajax ist ein Tool. Es ist keine Denkweise, keine Philosophie und auch kein Beweis für Coolness. Verwenden Sie es, aber nur dann, wenn es sinnvoll ist. Wie Scotty bei Star Trek sagt: "Wie oft muss ich es noch sagen? Verwenden Sie das rich tige Tool für die Aufgabe.« Beam me up, Scotty.
Wie Ajax funktioniert Ajax ist nicht so kompliziert, wie es auf den ersten Blick aussicht. Man muss eine Anfrage an den Server schicken, einen Service aufrufen, und Daten werden zurückgcliefert. Aber anstatt ein Formular abzusenden und eine neue Seite mit dem Ergebnis zu laden, küm mert sich Ajax um all diese Dinge im Kontext der aktuellen Seite.
294 I Kapitel n: Raus aus derSeite mitAjax
Ein spezielles Objekt, entweder Microsofts ActiveXObject oder das allgemeinere XML HttpRequest, kümmert sich um die asynchrone Kommunikation zwischen dem Server und dem Client. Asynchron meint, dass die Anfrage abgeschickt, der Client aber nicht gestoppt wird, um auf das Ergebnis zu warten. Es gibt keine Sanduhr, die anzeigt, dass der Rechner arbeitet, während Sie Däumchen drehen. Staudessen gibt der Client eine Funktion an, die aufgerufen werden soll, wenn sich der Status der Anfrage ändert. In dieser Funktion wird der Status geprüft, und dann werden in Abhängigkeit von seinem Wert die zurückgegebe nen Daten verarbeitet und meist in irgendeiner Form in die Seite eingebunden. Für den Anwender sieht das Ganze so aus, als ob der Vorgang auf der Seite selbst abliefe und keine Client/Server-Interaktion im Spiel wäre. Das einzige Indiz für eine Beteiligung des Servers ist ein ausdrücklicher Hinweis darauf. Nachdem wir nun den großen Überblick haben, wollen wir uns zunächst eine Ajax Anwendung anschauen und im Rest des Kapitels dann die einzelnen Elemente unter die Lupe nehmen. Ajax benötigt eine serverseitige Komponente. Ich verwende für dieses Buch PHP, weil PHP vennutlich eine der gebr:iuchlichsten Skriptsprachen s i t, die heutzutage genutzt werden. Zudem finde ich, dass unter den verfügbaren Serverskriptspmchen - Perl, Python, Ruby und PHP - PHP diejenige ist, die JavaSctipt am meisten ähnelt.
Hallo Ajax-Welt! Sie können Ajax nutzen, um ein Drop-down-Feld in Abhängigkeit von einer Auswahl in einem anderen Feld zu befüllen. Das ist eine On-Demand-Lösung, die auch den Zugriff auf eine Datenbank reduziert. Zudem ist es ein sehr einfach zu erstellender Ajax-Effekt. Beispiel 13-1 enthält die Webseite mit dem Skript, das den Ajax-Server-Aufruf startet. Die Seite enthält auch noch ein Formular mit zwei select-Elementen: Eines enthält ein paar Werte, das andere keine.
Beispiel 13·j: Erste Ajax.Anwendlillg < ! DQCTYPE html PUBLIC "-IIW3CIIDTD XHTML 1.0 Transitional/lEN" "http://www. �3.org/TR/xhtmll/DTD/xhtm11·transitional.dtd"> <style type-"text/css"> div.elem { margin : 10px; <script type_"text/javascript"> 11 <Jscript> <Jhead> Bundesstaat auswählen: <select onchange_"populatelist()"> California Missouri<Joption> washington ldaho<Joption> Städte: <select>