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<:hierllich
Eine Site mit Verweisen aufverschierlene Emulatorffi und Tesl:tools ist: httpJ/www.wire/essdevrtt'l.cam!dtannels/
ser fiir drahtlose Gl'fate
prinrlink5.phtm/?w/egrJry=4
Wenn Sie Webseiten besuchen und sich fragen, wie dort ein bestimmtes Feature imple mentiert wurde, können Sie normalerweise an der Art der Deklaration des Skriptblocks erkennen, welche Version von JavaScript genutzt wird. Zusätzlich gibt es Teile dieser alten Sprachen, die immer noch die moderneren Versionen von JS beeinflussen. Wir werden den Skriptblock in diesem Kapitel später noch genauer betrachten, aber es ist wichtig, sich darüber im Klaren zu sein, dass alte Versionen von JavaScript und seinen Variationen immer noch Auswirkungen auf heutige Anwendungen haben. In diesem Buch nutze ich die Begriffe JavaScript und JS synonym. Sofern nichts anderes angegeben ist, basieren die Beispiele in diesem Buch auf EMCA-262 und JavaScript 1.5/1.6.
Browser-Inkompatibilität und andere Mythen über JavaScript Die Sprache JavaScript läuft in vielen verschiedenen Umgebungen und auf verschiedens ten Plattformen. Sie kann genutzt werden, um Webseiten (und andere Anwendungen) zu entwickeln, die unter Betriebssystemen wie Mac OS X, Windows und Linux laufen. Man
4 I Kapitel l: Einführungund erste Schritte
braucht keinen speziellen Download und keine besondere Installation, da JavaScript in allen Browsern eingebaut ist, für die Sie sich entscheiden. Die meisten Browser implementieren eine gemeinsame Untermenge der Sprache, wo durch der größte Teil des Codes über Browsergrenzen hinweg ziemlich kompatibel bleibt. Das kann zu Verwirrung führen: Wenn die Sprachimplementierung doch gleich ist, warum gibt es dann Probleme mit Inkompatibilitäten zwischen Browsern? Die meisten Inkompatibilitäten basieren mehr auf Unterschieden der Art, wie das zu Grunde liegende Document Object Model (DOM) vom Browser zur Verfügung gestellt wird, denn auf der Sprache selbst. So ist zum Beispiel ein Objekt der Sprache JavaScript ein Date oder ein String - und es wird auch dann ein Date oder ein String bleiben, wenn es in Safari oder dem Navigator implementiert ist. Eine Instanz eines Objekts vom DOM wäre das Objekt document, das den Teil des Browsers repräsentiert, der die Webseite beinhaltet. Die Art, wie diese DOM-Objekte bereitstehen und sich in der browserabhän gigen Implementierung von JavaScript (oder ECMAScript) anpassen lassen, sorgt für die Inkompatibilitäten zwischen den Browsern. Ein anderer Bereich, der für Verwirrung sorgt, hat etwas damit zu tun, was in der Web seite durch JavaScript beeinflusst wird und was durch Cascading Style Sheets (CSS) . Alles, was JavaScript mit einem Element einer Seite tun kann, ist, es zu erstellen, zu ent fernen oder seine Attribute anzupassen. Unter diesen Attributen sind auch solche, die durch das CSS-Attribut style definiert sind. CSS definiert das Aussehen und auch einen Teil des Verhaltens von Elementen auf der Webseite. Es kann Elemente verbergen oder anzeigen, die Farbe und die Schriftart ändern, Position und Größe anpassen, abschneiden und so weiter. Die Art, wie jeder Browser CSS implementiert, kann sich unterscheiden, und das kann auch zu Inkompatibilitäten führen. Alles, was JavaScript dabei tut, ist, lediglich die CSS-Style-Attribute eines Elements zu ändern. Konformität mit ECMAScript stellt sicher, dass alle eingebauten Objekte von JavaScript die gleichen sind, aber es kann zwischen den Browsern kleine Unterschiede geben. Die meisten Inkompatibilitäten zwischen Browsern in der Vergangenheit hatten aber ihren Ursprung in den Unterschieden im DOM oder im CSS.
Was Sie mit JavaScript tun können JavaScript fand seinen weitreichenden Einsatz zunächst bei einfachen Aufgaben: dem Überprüfen des Inhalts von Formularen oder dem Setzen und Auslesen von Cookies (kleine Informationseinheiten, die auch dann bestehen bleiben, wenn der Browser ge schlossen wird). In den späten 1990er-Jahren wurde JavaScript mit der Einführung von Dynamic HTML (DHTML) auch dazu genutzt, dem Benutzer durch Drop-down-Menüs und Ähnliches eine dynamischere Umgebung zu präsentieren.
Was Sie mitJavaScript tun könllen I 5
Die Beliebtheit von JavaScript wuchs - oder explodierte förmlich - in jüngster Zeit, da es eine Schlüsselkomponente in Ajax (Asynchronous JavaScript and XML) ist, durch die sich die Art, wie Webanwendungen mit dem Benutzer kommunizieren, komplett ändern soll. Mit der Zeit wurden viele Probleme, die durch unterschiedliche Plattformen ent standen, gelöst, und die Sprache wurde ausgereifter - mittlerweile so weit, dass Java Script nicht mehr nur eine Skriptsprache ist, sondern eine voll ausgestattete Program miersprache. Was können Sie also mit JavaScript tun? Nun, für den Anfang:
Formularfelder überprüfen Überprüfen Sie den Inhalt eines Formulars, bevor Sie es an den Server schicken. Damit sparen Sie Zeit und Serverressourcen und geben direkte Rückmeldungen.
Webcookies setzen lind auslesen Legen Sie Informationen wie Benutzernamen, Kundennummern oder VoreinsteIlun gen in einer kontrollierten, sicheren Umgebung ab - wodurch dem Benutzer Zeit gespart wird, wenn er das nächste Mal auf eine Site zugreift.
Die Erscheinung eines Seitenelements dynamisch ändern Geben Sie Rückmeldungen, indem Sie falsche Eingaben in einem Formular hervor heben; ändern Sie die Größe der Schrift auf Wunsch des Anwenders.
Elemente anzeigen lind verbergen Ausgehend von persönlichen Wünschen oder Aktionen von Benutzern zeigen oder verbergen Sie Seiteninhalte wie zum Beispiel Formularelernente, verändern Schriften und passen die sichtbare Größe eines Bilds an.
Elemente auf der Seite verschieben Erstellen Sie ein Drop-down-Menü oder bieten Sie einen animierten Cursor an, um Seitenelemente besonders hervorzuheben.
Fangen Sie Bemdzeraktionen ab lind passen Sie die Seite dementsprechend an Machen Sie abhängig von den Tastatureingaben oder Mausaktionen des Benutzers einen Teil einer Seite eingabebereit.
Inhalte scrollen Bei größeren Bildern oder anderen Inhalten stellen Sie eine Möglichkeit zur Verfü gung, um die Elemente mit der Maus oder Tastatur nach links oder rechts, oben oder unten serolIen zu können.
Kommunizieren Sie mit einer serverseitigen Anwendung, ohne die Seite Zll verlassen Dies ist die Basis von Ajax und wird genutzt, um Auswahllisten zu füllen, Daten zu aktualisieren und eine Anzeige zu erneuern - alles, ohne die Seite komplett neu laden zu müssen. Das hilft, Roundtrips mit dem Server zu reduzieren, wodurch man Zeit und Ressourcen sparen kann. Was können Sie also machen? Vielleicht sollte die Frage besser lauten, was Sie nicht tun können.
6 I Kapitel l: Einführungund erste Schritte
Ein erster Blick auf JavaScript: »Hallo Welt!« Ein Grund für die Beliebtheit von JavaScript ist, dass es recht einfach ist, einer Webseite JavaScript hinzuzufügen. Der einfachste Weg ist, HTML-Script-Tags in die Seite mit aufzunehmen, für das Attribut type JavaScript anzugeben und den gewünschten java Script-Codc cinzutippen: <script type_"text/javascript"> . . . 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">
Beispiel 1-1 <meta http-equiv_"Content_Type" content_"text/html; charset-utf-B" I> <script type_"text/javascript") var dt _ Date ( ) ; I1 sag Hallo var msg ' Hallo Welt I Heute ist ' alert(msg);
+
dt;
Kopiert man dies in eine Datei und öffnet sie in einem beliebigen Webbrowser, sollte man ein Miueilungsfenster erhalten, sobald die Datei geladen wurde. Wenn nicht, kann es gut sein, dass JavaScript im Browser abgeschaltet ist oder, was heutzutage selten sein dürfte, gar nicht unterstützt wird. Auch wenn dieses Beispiel einfach ist, zeigt es doch die grundlegenden Komponenten der meisten JavaScript-Anwendungen, die heutzutage genutzt werden. Es lohnt sich, das Beispiel genauer anzuschauen.
Ein eriter BlidaufJavaSuipt: »Hallo Weh!« I
7
Die Beispiele in diesem Buch sind alle so emworfen, dass sie gültiges XHTML sind, was bedeutet, dass sie DOCTYPE, den Dokumentemitel und den Con tem-Type enthalten. Sie können diese Elemente ignorieren, wenn Sie die Bei spiele selbst erstellen. Besser ist es aber, eine Webseitenvorlage als Rahmen zu erstellen, die DOC1l'PE, Dokumentemitel, Coment-Type, Head und Body emhält, die Sie dann für die meisten Beispiele kopieren.
Das saipt-Tag javaScript ist anders als andere Sprachen immer in den Kontext einer weiteren Sprache eingebettet, wie zum Beispiel HTML oder XHTML (beides sind tatsächlich Sprachen, auch wenn das nicht ganz so offensichtlich zu sein scheint). Damit meine ich, dass es Einschränkungen dabei gibt, wie das Skript der Seite hinzugefügt wird. Sie können nicht einfach irgendwo und irgendwie auf der Seite jS-Code fallen lassen. Auch wenn man JavaScript in einem anderen, webfreien Kontext nutzt, ist es häufig ein Teil eines Dokuments oder einer Vorlage.
In Beispiel l-! umschließt das (X)HTML-Tag script den javaScript-Code. Damit weiß der Browser, dass er den Inhalt dieses Tags nicht als HTML oder XHTML interpretieren soll. An diesem Punkt wird die Kontrolle über den Inhalt an einen anderen Bereich des Browsers übergeben, die Scripting Engine_ Nicht jedes Skript, das in Webseiten eingebettet wird, ist javaSeript, und das Tag enthäh
ein Attribut, das den Typ des Skripts angibt. Im Beispiel ist dieses als text/javascript definiert. Andere zugelassene Werte für das Attribut type sind: •
text/ecmascript
•
text/jscript
•
textlvbscript
•
textlvbs
Der erste Wert ist eine Alternative zu JavaScript, der zweite eine Abwandlung von java Script, die von Microsoft im Internet Explorer implementiert, ist und die letzten beiden stehen für VBScript. Alle diese Werte von type beschreiben den MIME-Typ des Inhalts. MIME, oder auch Multipurpose Internet Mail Extension, ist eine Möglichkeit zu beschreiben, wie der Inhalt codiert ist (zum Beispiel text) und welches spezifische Format genutzt wird (javaseript). Dieses Konzept entwickelte sich im E-Mail-Bereich, wanderte dann aber auch in andere Internetecken, zum Beispiel hier beim Festlegen des Skripttyps in einem solchen Block.
8 I Kapitel l: Einführungund el"5te Schritte
Indem man einen MIME-Typ angibt, verarbeiten die Browser, die dazu in der Lage sind, den Code, während die anderen den Bereich überspringen. Damit ist sichergestellt, dass das Skript nur von Anwendungen genutzt wird, die damit umgehen können. Frühere Versionen des script-Tags hatten ein Attribut language, das dazu genutzt wurde, die Version der Sprache und den Typ festzulegen: javascript im Vergleich zu javascript 1.2. In HTML 4.01 wurde language zwar als veraltet (deprecated) ausgewiesen, findet sich aber immer noch in vielen javaScript-Beispielen. Und hier kommen wir zu einer der frü hesten browserübergreifenden Techniken. Vor vielen jahren war es beim Berücksichtigen von Kompatibilitätsfragen zwischen Brow sem nicht unüblich, ein spezifisches Skript für jeden Browser in einem eigenen Abschnitt oder einer eigenen Datei zu erstellen und dann mit dem Attribut language sicherzustellen, dass nur ein kompatibler Browser auf den Code zugreifen kann. In einigen meiner alten DHTML-Beispiele (von etwa 1997) fand ich das Folgende: <script src-"ns4_obj.js" language_"javascriptl.2"> <script src-"ie4_obj.js" language_"jscript"> Die Philosophie dieses Ansatzes war, dass nur ein Browser, der JavaScript 1.2 verarbei ten konnte, sich den ersten Block schnappen würde (damals vor allem Netscape Navi gator 4.x), während ein Browser, der jScript beherrschte, die entsprechende Datei nut zen würde (Internet Explorer 4). Klingt nach einer Notlösung? Sicher, aber es half ungemein dabei, die ersten jahre mit häufig nicht funktionierendem browserübergrei fendem DHTML zu arbeiten. Schließlich ging man dazu über, einem Ansatz namens Object Detection (Objekterken nung) zu folgen - was durch die Einstufung des language-Attributs als veraltet noch ge fördert wurde. Wir werden uns die Objekterkennung in späteren Kapiteln noch genauer anschauen, insbesondere in dem zu Ajax. Kurz gesagt, geht es bei der Objekterkennung darum zu prüfen, ob ein bestimmtes Objekt oder eine Eigenschaft eines Objekts existiert. Wenn das der Fall ist, wird ein javaScript-Bereich verarbeitet, ansonsten ein anderer. Zurück zum script-Tag. Andere gültige Attribute für dieses Tag sind src, defer und charset. Das Attribut charset definiert die Zeichenkodierung, die im Skript genutzt wird. Solange Sie für den Code keine andere Kodierung brauchen als für das Dokument, wird dieses Attribut normalenveise nicht gesetzt. Ein Attribut, das ziemlich nützlich sein kann, ist defer. Wenn das Attribut defer den Wert defer erhält, teilt dies dem Browser mit, dass das Skript keinen Dokumenteninhalt erzeugen wird und der Browscr mit dem Verarbeiten des Rests der Seite fortfahren kann, um das Skript nach dem Abarbeiten und Anzeigen der Seite einzulesen: <script type_"text/javascript" defer_"defer"> . . . kein generierter Inhalt
Ein eriter BlidaufJavaSuipt: »Hallo Weh!« I 9
Dies kann dafür sorgen, dass die Ladezeiten für die Seite verringert werden, wenn Sie einen größeren JavaScript-Block haben oder eine große JS-Bibliothek einbinden. Das letzte Attribut sre hat mit dem Laden solcher Bibliotheken zu tun, und wir werden es gleich noch behandeln.
Speichermöglichkeiten für JavaScript-Code In Beispiel I - I ist der JavaScript-Block in das head-Element der Webseite eingebettet. Das Skript kann auch im Body aufgenommen werden, wie eine geänderte Anwendung in Beispiel 1-2 zeigt. Beispi el J ·2: Jal'aScript ill deli Body des Dokumellts einbetteIl
< I OOCTYPE html PUBLIC "-IIW3CIIDTD XHTML 1.0 TransitionalllEN" "http://www.w3. org/TR/xhtm11/DTD/xhtm11-transitional .dtd">
Beispiel für Java$cript.Codeblöcke <meta http-equiv_"Content_Type" content."text/html; charset_utf_B" I> <script type_"text/javascript"> 11<1 [CDATA[ var dt _ Date ( ) ; var msg . ' Hallo Welt I Heute ist ' document.writeln (msg);
+
dt
+
'
';
11]]>
10 I
Kapitel l: Einführung und erite Sduine
Das Einfügen von JavaScript im Body kann auch komplett vermieden werden, indem man das DOM nutzt, um neue Inhalte zu erstellen und sie den Seiten elementen zuzuweisen. kh werde dieses Vorgehen sp:iter in diesem Buch noch vorstellen.
Das Skript verbergen In Beispiel 1-2 wurde der Skriptblock innerhalb eines XHTML-CDATA-Abschnitts einge fügt. Ein solcher Abschnitt enthält Text, den der XHTML-Prozessor nicht interpretiert. Der Grund für die Nutzung eines CDATA-Abschnitts liegt darin, dass XHTML-Prozesso ren Markups wie zum Beispiel die Tags für die Überschrift (H3) interpretieren, auch wenn sie innerhalb von JavaScript-Strings stehen. Auch wenn die Seite trotzdem korrekt ange zeigt werden wird, können Sie Fehlermeldungen erhalten, wenn Sie versuchen, die Seite ohne den COATA-Abschnitt zu validieren. Bei JavaScript, das mit Hilfe des Attributs src auf die Seite importiert wird, wird davon ausgegangen, dass es zu XHTML kompatibel ist und weswegen keinen COATA-Abschnitt benötigt. Inline- oder eingebettetes JS sollte aber mit CDATA umschlossen werden, insbe sondere wenn es im Element body eingebaut ist. Bei den meisten Browsern müssen Sie auch die öffnenden und schließenden Tags für den COATA-Abschnitt mit JavaScript-Kommentaren (11) ')verbergen«, da Sie ansonsten einen JavaScript-Fehler erhalten. JavaScript Best Practice: Die Verwendung sowohl des CDATA-Abschnitts als auch der JavaScript-Kommentare ist so wichtig, dass sie die ersten von vielen JavaScript BeSt Practices bilden, die in diesem Buch behandelt werden. Wenn Sie einen XHTML-DOCTYPE nutzen, umschließen Sie Inline- oder ein gebettete JavaScript-Blöcke in CDATA-Abschnitten, die dann mit Hilfe von JavaScript-Kommentaren auskommentien werden. Und stellen Sie immer sicher, dass Ihre Webseiten in XHTML geschrieben sind, daher nutzen Sie immer CDATA. Es ist natürlich der beste Weg, Ihre Webseiten nicht mit JavaScript zuzumüllen, sondern den JavaScript-Code komplett von der Seite zu entfernen und auf JavaScript-Dateien zurückzugreifen. Viele der Beispiele in diesem Buch sind vor allem deshalb in die Seiten eingebettet, um sie leichter erstellen zu können. Die Mozilla Foundation allerdings em pfiehlt, allen Inline- oder eingebettetenJavaScript-Code von einer Seite zu entfernen und in eigenständige JS-Dateien auszulagern. Damit vermeidet man Probleme mit der Validie rung und falschen Interpretation von Text, unabhängig davon, ob die Seite als HTML oder XHTML verarbeitet wird.
Ein erster Blkk aufJavaSaipt: ..Hallo Welt!c I
l'
JavaScript Best Practice: Bringen Sie alle Blöcke mit JavaScript-Code in ex ternen JavaScript-Dateien unter.
JavaScri pt-Dateien Als JavaScript objektorientierter und komplexer wurde, begannen Entwickler damit, wie derverwendbare JS-Objekte zu erstellen, die sich in vielen Anwendungen verschiedener Entwickler nutzen ließen. Der einzige effiziente Weg, diese Objekte wiederverwenden zu können, war das Erstellen in eigenen Dateien und das Bereitstellen eines Verweises auf jede Datei auf der Webseite. JavaScript-Dateien sind auch aus anderen Gründen als dem der Wiederverwendbarkeit nützlich. Anstalt zum Beispiel den gleichen Code auf vielen Webseiten zu wiederholen und ihn bei Änderungen an all diesen Stellen anzupassen, wird der Code in einer Datei erstellt, und alle Modifikationen werden dann nur an einer Stelle vorgenommen. Heutzu tage werden alle bis auf die einfachsten JavaScript-Anwendungen in eigenen Skriptdateien erstellt. Jegliche Mehrbelastung durch die Verwendung mehrerer Dateien wird bei Wei tem durch die Vorteile aufgewogen. Um eine JavaScript-Bibliothek oder eine Skriptdatei in Ihre Webseite einzubinden, ver wenden Sie die folgende Syntax: <script type_"text/javascript" src_"somejavascript .js"> 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">
Beispiel 1-3<Jtitle> <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>
'"§
Der Inhalt von noscript kann auch noch bei einer anderen Gelegenheit aus gewertet werden: wenn nämlich im Browser oder einer anderen Anwendung JavaScript aktiviert ist, der MIME-Typ des Skriptblocks aber nicht verarbeitet werden kann. Allerdings ignorieren viele bekannte Srowser, wie Firefox oder Safari, in diesem Fall den Inhalt von noscript. Das ist ein Fehler, den Sie im Kopf haben müssen, wenn Sie auf noscript angewiesen sind.
Eine Alternative zu noscript Je mehr Sie einer Webseite hinzufügen, desto schwieriger ist es, sie zu betreuen. Wenn SieJavaScript venvenden, um viel Funktionalität bereitzustellen, und dann noscript nut zen, um Alternativen zu bieten, können Ihre Seiten groß und kompliziert werden. Ein anderer Ansatz, einen, den ich empfehle, wenn Sie den Inhalt von Webseiten auf Grund von Benutzeraktionen anzeigen oder verbergen wollen, ist der Entwurf der Seite
Barrierefreiheit und Beil Practices I 21
mit statischen Elementen. JavaScript wird dann dazu genutzt, diese Elemente entweder zu verbergen und den alternativen dynamischen Inhalt anzubieten oder tatsächlich die statischen Elemente stehen zu lassen und die dynamischen als zusätzliche Option bereit zustellen. Die bekannte Fotosite Flickr (http://flickr.com) nutzt diese Technik. Wenn Sie eine be stimmte Fotoseite als Besitzer des Fotos anzeigen, sehen Sie unabhängig von aktiviertem oder deaktiviertem JavaScript einen Venveis, den Sie anklicken können, um den Titel des Fotos, Tags und die Beschreibung zu bearbeiten. Ist JavaScript aktiviert, können Sie zu dem auf den Titel oder die Beschreibung klicken, um direkte Bearbeitungsmöglichkeiten zu haben. Zudem gibt es einen eigenen Venveis "Add a tag«, mit dem man ein Eingabe feld für das Hinzufügen eines neuen Tags erhält, wie in Abbildung I -I zu sehen ist.
Ibutterfly21 .I:'!ilDI rn
CAIICEL
I
... U�eOooJa� 12.2006 Illil! tI'y .ll.lr:!!.!!all +
Burningora', pnol"tean
BUllerfiles, Molhs, D,egonflles, end Bees (Sei)
Tag'
-; BlJn'r1I/liou,e ',: �i"ou-i 80lani
Jn,my
,----- ... cnoose trom )
Separal' eacn laJ "ith a ,pace' oam"""�h"'. utbanm'blog. ÜllOjoin 2 wora' lOge"er ln 0"" lag, use OOL.()le qL.Ote>: "cIoilyromtru""
Add your comment
Additianal lnlmmalion liJ CAI ,..,blS r�,,,,,,eool o T.ke, wttI . Nkor 0'0 M«ep
...
o V, ,.d 11 �tm... INot ..,.drgy"'-'I o EIl ttle. ;<"r�t""', """ t:l
Abbildung
1 , 1 : DHTML lInd Ajax bei Flieh
Wenn JavaScript deaktiviert ist, passiert beim Klicken auf den Titel oder die Beschreibung gar nichts, und der Venveis zum Hinzufügen von Tags ist nicht zu sehen. Da das CSS Attribut display unabhängig von JavaScript ist, werden die Elemente verborgen, wobei es keine Rolle spielt, ob JavaScript aktivicn ist oder nicht.
22 I
Kapitel l: Einführung und erste Sduitte
Wenn Skripting aktiv ist, können Sie JavaScript verwenden, um die vorher verborgenen Objekte anzuzeigen, falls der Besucher der Webseite die Elememe anklickt. Dabei wer den Evem-Handler mit Seitenelememen wie dem Titel oder der Beschreibung verknüpft. Was ich bei Flickr nicht gut finde, ist der Hinweis, dass /!I1r mit einem JavaScript-fähigen Browser diese oder jene Funktionalität genutzt werden kann, wie das in Abbildung 1-2 zu sehen ist. Das Problem dabei ist, dass manche Menschen gar nicht dazu in der Lage sind, JavaScript zu nutzen. Diejenigen, die es können, sich aber dazu emschieden haben, JavaScript zu deaktivieren, tun dies im Allgemeinen aus guten Gründen, und sie werden diese nicht nur wegen einer Website über den Haufen werfen - egal wie sehr sie diese Site mögen. Das Anzeigen einer Meldung ,)nur, wenn« entspricht dem Hinweis »Sie benöti gen den Internet Explorer, um diese Seiten zu betrachten«, der Ende der 1990er-Jahre sehr verbreitet war. Es war damals eine schlechte Idee, den Besuchern zu erzählen, was sie zu tun haben - und es ist auch heute eine schlechte Idee.
butterfly21 10 tak. MI iId.antd�e of fliu.r, yoo >110,1<1 "50 " J"".:5cAipt..""bl.d brow>« .r
BL.mingbird·, photl'tr.,m
IIIOlh5, Dr�gonflles. arn:l Bees (Set)
8utterfllu,
Tags '} BJtI>rny Hcma '} MI,.ru[1
��I
Ga[�OO
'} butlOrny
Addi�on.llnforma!ion
fiI O/IJI'iI"" ,........, «
__I ' o la<..,Wln aH"",DlO o o o o o
""'. ,...,... ",'''' OOJ........,. [2,20!10 1"'1 s...�rl.'"<W'. , IO t....'. (N"' '''....� Y''''I E
Abbildung J -2: Flieh-Seite mit deaktiviertem JavaSeript !//Id der »Iwr, we/l/I,,-Meldung Sie können dann auch gleich ein großes Bild mit der Aufschrift »Mann, du nervst« anzei gen, denn im Grunde sagen Sie das mit so einer Meldung.
Barrierefreiheit undBeil Practices I 23
Ihren Browser und andere Entwicklungstools nutzen Als JavaScript das erste Mal implementiert wurde, war die Akzeptanz gering, da es keine Skript-Debuggcr oder Entwicklungstools für die Sprache gab. Heute aber haben die meisten Browser eingebaute JavaScript-Konsolcn oder andere Tools, um die JavaScript Entwicklung und den Debugging-Prozess zu vereinfachen. Firefox hat eine JavaScript-Konsolc (seit Version 2.0 mit dem Namen »Fehler-Konsole«), die Fehler und Warnungen ausgibt. Sie ist erreichbar, indem man in der Statuszeile ein Symbol anklickt (entweder ein 5toppzeichcn bei einem Fehler, ein Warndreieck oder eine Sprechblase mit einem kleinen i) oder im Menü EXTRAS den Eintrag FEHLER-KONSOLE wählt. Diese Konsole stellt Debugging-Informationen für jede Seite bereir und hält diese vor, bis Sie den Inhalr der Konsole explizir löschen (siehe Abbildung 1-3).
====::::J :::= tc=:::;:== 8
"�M
_ " not cIdlned
"" ""*,,, " C , qmp! .1 teq ,. , twwwt ol:! P
ZeIo:
1
1
9
==::::!.m'!COOfJIQ!l,i>
9
teq ,. , twwwt ol:! P """" ' ! C "Uo qmp! .1f
ZeIo:
==�!!COOfllQ[).1!;
z...: 2
8 8
_ " not dd""med
....uought C>I.. : p t illn: ON: Erlaubnioliir den Auf'"...". Methode locatioR.toString ........, ,...,.c ... io<:tt Ii"bokorrte � 'saohr·lIIo;tt-olb:'. DeI:lorotlDn 1fTaIert.
tup." ....c ..m
-,
"
�e �·=ohr·�. De+>oralioniopJriert. lUD " · ....e m< .. oIoYcatIIleomll�e�. CS H SS
-,
"
Ii"bokorrte � ·=ohr�. OeI
....c m< .. Ql.rru! 1Ilc pm!t orrpL:c a lc« lIlc qrmpoIw !ter e rl:Qt cu cu tup."
-, "
�.� ·=ohr�_. DeIdoralion iQ"'-. ... oIoYcatIIleOOJIl�'" e�. <ss.w
-,
«
-,
•
Ii"bokorrte � ·=ohr�oce-cob'. OeI
Abbildung 1-3: Felller-KOllsole i/I Firefox Firefox bietet auch einen DOM-Inspector. Dabei ermöglichen sehr nützliche Tools es Ihnen, die DOM-Objekte auf der Seite zu untersuchen, wobei man die folgenden hilfrei chen Informationen erhält (der Computed Style ist in Abbildung 1-4 abgebildet):
24 I
Kapitel l: Einführung und erite Sduine
DOM Node Knotenname, Typ, Klasse, Namensraum-URI und Wen.
Box Model Position, x- und y-Wene.
ComplIted Style Die Standardeigenschaften des Objekts.
XBL Binding Die Extensible Binding Language (nicht Thema dieses Buchs).
CSS Style RlIles Die CSS-Style-Regcln, die standardmäßig für ein Element genutzr werden und im Stylesheet definiert sind.
QOot.
I:ij
rn -
�_ �hon 141
_
t!l.
",,,,1_. .,,,, "", ,,, ,,, "' "'-
oD..r. � . "",, _
,. "
m.
,�.
",�� · (""", . B''''
"
'_hol' b_·__ brl<>o.ro�", -� b_·.--,
,-
_....,"'""''''
"'
t;:f',mKOO t;:�""", t;:;,:: t;�-
-
'"' ,..""......
"
'''''. '.')
.... .....,..
" "'"
••
.... .,...
-,.�",
"0.<'
_.
_.� tK
"."
_. -
•
"."
-
�-
-�."" , [::,� , [b' ::.:_ E-� t:� -
""�Jo"""'... ....,.("<""'� - ,_.
'..�... '''''.0.') "'
'''''.0.') "'
..� ."'ßO.O) .. •• "
•. '''''.'.01
.,
•
.� ,..do.. oo ........k.'....�·_.f '"
�" �. -
•.
y
Abbildung 1-4: Computed Style im DOM-Inspector des Firefox Das in Abbildung 1-5 gezeigte JavaScript-Objekt ist von besonderer Bedeutung, da es eine Liste mit Events, Eigenschaften, Attributen und Funktionen bereitstellt, die das Ob jekt in JavaScript anbietet.
Barrierefreiheit und Beil Practices
25
i:a
'" I�t."-,,,,,, ,..,."'...._
!lI - - ""' '''''' �"'" �
•
� .�+
..
'_rn"''''''....o(H .,.
'""
-""''''
• ,,"w
["""",000])
[_,cs�.o.."'_J ,,,,,,,, � j
["""" ""I)
,.. ".....
-.. � """',.'"
ru.
.'",,'
'OIV'
-' ,�" �"" .,d;,*,""',
,.,
..-
[_,",tu."_l
. """..,
[_, HI,u"""""'l
I
,.,
[_'HI�l [_'HI.....""""""'1 [-' '''']''''"
[_'HI'U""""",," ,.,
[_' .........''1'1
;"_F�
. ,,"'-"" ",",-""" ,�� "".o.,
F_�"�'....o(J . j
[""'''' '''''])
,,,,,,,, ,,<,=<:bId:)j
[00<",,000])
'_rn,,,,,od>Oo;Jj ,,,
[""", ,,,;,]) ["""" 00."
'_rn""'"" """"'0j
[n.",."""'])
,_� � ! ,""""' '''',,,,){ ''
�--])
'''''''' ,,,-,,'o<:){
[-..._])
,.,
'OIV' ..,
,..-ho"""".:) "" !
"ox' ..
-
__tt'",,, ......,"""'''''' ,..-- ""'''''',' ,w_ ...""""," " "", ......,""'", ,�"'
'''''''' _'''''o(Jj ''
[not........]} ["""" ""'1)
'_rn,_){
[o",,. ,,,,
,_�""",,,,",""""'0< ["""." F_� "'''''''''''''''''I { [n..... . ' ,,,,,,,, ,,,,,-tMoQj ,,,
[""",
'_rn",�._T_-:]{ '_rnoo"'''''oN>{]{ ''
[",
"""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"> Geltungsbereich <meta http-equiv_"Content_Type" content_"text/htmlj charset-utf-8" I> <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
Gellungsbereidl
I B
Lädt die Seite, wird der JS-Code im head-Element zuerst ausgeführt und die Variable
message auf einen String mit den Worten Ich bin auf der Seite gesetzt. Die Variable wird dann in der Funktion testScope ausgegeben, wobei die Funktion aufgerufen wird, wenn die Seite mit dem Laden fertig ist. Vor der Ausgabe wird aber in der Funktion am Ende des Strings noch der Text aufgerufen in testScopeO angehängt. Weiter unten auf der Seite greift ein anderer JavaScript-Block auf message zu und hängt seinen eigenen Text an den String an: eingebettet in der Seite. Der angepasste String wird dann auf der Web seite ausgegeben. Die Seite importiert auch zwei externe JavaScript-Dateien. Die erste, global.js, verkettet ihren eigenen String global in globalPrint mit message. Die Quelldatei enthält weiterhin eine Funktion globalPrint, in der ein Dialogfenster geöffnet und die Mitteilung ausgege ben wird: if (typeof(message) 1 _ 'undefined ' ) message +_ " global in globalPrint"; function globaIPrint( ) ( alert(message) ; Die letzte Komponente dieser Anwendung, die JavaScript-Quelldatei globaI2.js, enthält eine Funktion globa12Print und passt ebenfalls message an, dieses Mal ergänzt um auch
in globa12Print genutzt: function globaI2Print ( ) ( message +_ " auch in global2Print genutzt"; alert(message) ; ) Wenn die Webseite geöffnet wird, wird message das erste Mal im ersten Skriptblock ge setzt, dann im zweiten Skriptblock während des Ladens der Seite verändert und ausgege ben. Die Nachricht lautet an dieser Stelle: Ich bin auf der Seite eingebettet in der Seite Das ist nicht allzu überraschend. Über das Event onload im Tag body wird testScope auf gerufen, sobald die Seite geladen ist. Die Funktion verändert den String und gibt ein Fenster mit folgendem Text aus: Ich bin auf der Seite eingebettet in der Seite aufgerufen in testScope() Klickt man auf die Schaltfläche OK, wird das Fenster geschlossen und die nächste in onload aufgeführte Funktion aufgerufen: globa12Print in globaI2.js. Diese Funktion hängt ein "du warst auch bei mir« an, und man erhält folgende Ausgabe im Fenster: Ich bin auf der Seite eingebettet in der Seite aufgerufen in testScope() auch in giobal2Print genutzt Die Nachricht wird immer länger und wurde in verschiedenen JS-Blöcken in zwei Da teien verändert, aber sie ist noch nicht fertig. Die letzte Funktion, die im Event onload aufgerufen wird, ist globalPrint in global.js. Hier wird die Mitteilung nochmals geändert und via alert von globalPrint ausgegeben. Das Ergebnis ist:
34 I
Kapitel 2: Datentypen und Variablen
Ich bin auf der Seite eingebettet in der Seite aufgerufen in testScope() auch in globa12Print genutzt An dieser Stelle kann es sein, dass Sie der Inhalt von message verwirrt. Wie Sie sehen kön nen, hat sich die Nachricht zwischen den Aufrufen der Funktion in global2.js und der Funktion in global.js nicht geändert, aber javaScript hat in beiden Dateien den String modifiziert. Der Unterschied im Ergebnis kommt dadurch zu Stande, dass global2.js den String direkt vor der Ausgabe in der Funktion anpasst und ihn als lokale Variable behandelt, während global.js ihn außerhalb der Funktion verändert und als global behandelt. Wird die java Script-Quelldatei geladen, wird auch der javaScript-Code beim Laden der Seite abgear beitet, und die global gesetzte Meldung geht verloren, sobald der javaScript-Code im Element head der Webseite verarbeitet wird. Der Skriptblock behandelt message als lokale Variable und setzt den Inhalt der Variablen (anstalt sie zu modifizieren) - wodurch der Wert aus der globalen Variablen mit dem gleichen Namen überschrieben wird. Nach ein paar mehr direkten und indirekten Sprüngen und dem Mischen von globalem und lokalem Zugriff auf eine Variable, wobei sich die beiden Varianten nicht unterschei den lassen, werden Sie überrascht sein, was für ein Ergebnis am Ende herauskommt egal wie sorgfältig Sie den Weg der Variablen verfolgt haben. Garantiert. Auch wenn es hier nicht vorgeführt wurde, hat eine Variable, die innerhalb eines Codeblocks (begrenzt durch geschweifte Klammem) deklariert wurde, einen Geltungsbereich, der über den Block hinausgeht. Sie lässt sich in der gesamten Funktion (oder einem Skript, wenn der Block sich nicht innerhalb einer Funktion befindet) ansprechen. JavaScript 1.7 bietet auch auf Blöcke beschränkte Geltungsbereiche, aber diese Sprachversion ist zurzeit noch nicht in allen Browsern implementiert. Was ist die Moral von der Geschichte? Nun, es gibt zwei beachtenswerte Punkte. Der erste ist, dass man besonders vorsichtig sein muss, wenn man globale Variablen nutzt. Manch einer würde sicher so weit gehen zu sagen, dass man auf Grund der Möglichkeiten von JavaScript, Objekte zu erstellen und Eigenschaften zuzuweisen sowie Werte als Funk tionsparameter zu übergeben, keine globalen Variablen nutzen sollte. Aber globale Vari ablen können auch sehr praktisch sein - man kann sie als Zähler nutzen, sie können Timer speichern oder beliebige Werte vorhalten, die in mehr als einer Funktion notwendig sind. Aber egal wie sorgfältig Sie vorgehen - bei der Verwendung großer javaScript-Biblio theken kann es vorkommen, dass es eine globale und eine lokale Variable mit gleichem Namen gibt. In diesem Fall werden Sie unerwartete Nebeneffekte entdecken.
Gellungsbereidl
I 35
Ein weiterer Grund, globale Variablen zu venneiden, ist der Speicherver brauch einer JS-Anwendung. Die Speicheryerwaltung wird uns bei JS abge nommen, aber wir können dem Prozess unter die Anne greifen. Anders als lokale Variablen, die nach Beendigung der Funktion freigegeben werden, lungern globale Variablen herum, bis die Webseite und die JS-Anwendung nicht mehr länger im Browser geladen sind. Der ausgesprochen vorsichtige Umgang mit globalen Variablen ist die eine Lehre. die man ausn diesem Abschnitt ziehen konnte - was ist aber die zweite? Ganz einfach: Definieren Sie eine lokale Variable immer explizit mit dem Schlüsselwort var. Wenn Sie das nicht tun, wird sie als globale Variable behandelt - schlicht und einfach. JavaScript Best Praetice: Nutzen Sie das Schlüsselwort Vilr, um alle Variablen unabhängig von ihrem Gelrungsbereich zu deklarieren: global oder lokal. Wie das alte Sprichwort lautet: Fangen Sie so an, wie Sie weitermachen wollen. Das ist insbesondere dann gültig, wenn Sie JavaScript lernen.
Widgets tür JavaScript Nach einem langen, harten Tag der Arbeit mit Gelrungsbereichen von Variablen möchte ich ein bisschen Zeit zur Entspannung haben und mit Schnickschnack herumspielen: Spaßprogramme, Spielzeuge, etwas, das sich schnell installieren und intuitiv und einfach nutzen lässt. Ich habe sowohl ein Mac- als auch ein Windows-Notebook und mag beide, bevorzuge aber doch den Mac. Eines der Dinge, die ich besonders an meinem Mac mag, ist die Anzahl an Widgets, die ich in meinem Dashboard installieren kann - der Widget Space, der die Inhalte überlagern kann. Es ist ein wunderbarer Ort für Kinkerlitzchen, auch für welche, die sich um JavaScript drehen. Auf meinem Mac sind dabei unter anderem installiert: HTML Test 2, mit dem man Java Script testen kann, Execscript 2.0, dasJS ausführen kann, das man in einem Fenstereingibt, Regex, das Überlebenspaket für reguläre Ausdrücke, und Rob Rohan, eine Javascript Shell. Die meisten Javascript-Widgets lassen sich in der Kategorie »Developer« der Down load-Site für Widgets finden: http://www.apple.com/downloadsldashboardldeveloperl. Jedes ist mit nur einem Klick auf eine Schaltfläche installierbar und verbraucht minimale Ressourcen.
36 I
Kapitel l: Datentypen und Variablen
Einfache Typen JavaScript ist eine schlanke Sprache, die gerade genug Funktionalität besitzt, um ihre Aufgabe zu erfüllen - nicht mehr und nicht weniger. Aber wie ich schon sagte, ist es in manchen Dingen eine sehr venvirrendc Sprache. $0 gibt es zum Beispiel nur drei einfache Datentypen: string, numeric und boolean. Jeder wird durch seinen Inhalt unterschieden: Strings, Zahlen und Boolcschc Werte. Es gibt aber auch eingebaute Objekte, die als number, string und boolean bekannt sind. Sie scheinen das Gleiche zu sein, sind es aber nicht: Die ersten drei sind Varianten von pri mitiven Werten, während die letzten drei komplexe Konstrukte mit einem eigenen Typ sind: object. Anstatt Typ und Objekt in den nächsten drei Abschnitten durcheinanderzumischen, wer den wir uns jeden der einfachen Datentypen anschauen, ihre Erstellung betrachten und sehen, wie man Werte des einen Typs in einen anderen konvertiert. In Kapitel 4 werden wir uns diese und andere in JS eingebaute Objekte sowie deren Methoden und Eigen schaften vornehmen.
Der Datentyp String Eine Variable vom Typ string wurde in Beispiel 2-1 gezeigt. Da JavaScript eine Sprache mit loser Typbindung ist, gibt es keine Möglichkeit, diese Variable von einer numerischen oder Booleschen Variablen zu unterscheiden, es sei denn anhand des Werts, der ihr zuge wiesen wurde, oder dem Kontext, in dem sie genutzt wird. Ein String-Literal ist eine Folge von Zeichen, die durch einfache oder doppelte Anfüh rungszeichen umschlossen sind: "Dies ist ein String" 'Aber dies ist auch ein String' Es gibt keine Regel dafür, welche Anführungszeichen Sie zu nutzen haben, außer der, dass das schließende Anführungszeichen das gleiche sein muss wie das, mit dem Sie das Literal geöffnet haben. Jegliche Zeichen können in einem String vorkommen: "Dies ist 1 String." "Dies ist . - ein anderer String . " Nicht alle Zeichen werden in JavaScript in einem String gleich behandelt. Ein String kann auch Escape-Sequenzen enthalten, wie zum Beispiel \n für das Zeilenendezeichen. Eine Escape-Sequenz ist eine Reihe von Zeichen, in der bestimmte Zeichen kodiert sind, um sie im String aufzunehmen. Der folgende Codeschnipsel weist einer Variablen ein String-Literal zu, das ein Zeilenendezeichen enthält. Wenn der String in einem Dialog fenster genutzt wird, wird die Escape-Sequenz \n als Zeilenende interpretiert und eine neue Zeile begonnen: var strins_value
a
"Dies ist die erste Zeile\nDies ist die zweite Zeile" ;
Einfache Typen
I 37
Das Ergebnis ist: Dies ist die erste Zeile Dies ist die zweite Zeile Die beiden verschiedenen Arten von Anführungszeichen, einfache und doppelte, können gemeinsam genutzt werden, wenn Sie in einem String-Literal Anführungszeichen be nötigen: var string_value _ "Dies ist ein ' String' mit Anführungszeichen." oder: var string_value _ 'Dies ist ein "String" mit Anführungszeichen. ' Sie können auch den Backslash nutzen, um anzugeben, dass das Anführungszeichen im String als Anführungszeichen interpretiert werden soll und nicht als Ende des Strings: var string_value _ "Dies ist ein \"String\" mit Anführungszeichen." Um einen Backslash in einem String unterzubringen, venvenden Sie zwei Backslashs hin tereinander: var string_value _ "Dies ist ein \\String\\ mit einem Backslash . " Als Ergebnis dieser Codezeile erhalten Sie einen String mit zwei Backslashs, einem auf jeder Seite des Worts String. Es gibt auch eine JavaScript-Funktion escape, die einen kompletten String kodiert und ASCII in die URL-Kodierung (ISO Latin-I [ISO 8859-1]) umwandelt, die sich bei der Verarbeitung von HTML nutzen lässt. Das ist insbesondere dann wichtig, wenn Sie Da ten für Webanwendungen verarbeiten. Beispiel 2-2 zeigt, wie escape mit verschiedenen
Strings arbeitet.
Beispiel 2-2: Strlngs mit der Flmktion escape kodieren < I DOCTYPE html PUBLIC "-IIW3CIIDTD XHTML 1.0 TransitionalllEN" "http://www,w3,org/TR/xhtmll/DTD/xhtm11-transitional.dtd"> Dbjekte in Strings unwandeln <meta http-equiv_"Content_Type" content_"text/html; charset_utf_8" I> <script type_"text/javascript"> 11<1 [CDATA[ var sOne _ escape("http: //oreilly.com"); document.writeln ("" + sOne + "
"); var sTwo escape("http: //burningbird .net/index.php?pagename_$1&page_$2"); document.writeln ("" + sTwo + "
"); •
11]]>
38 I
Kapitel l: Datentypen und Variablen
Als Ergebnis dieses Programms erhält man die zwei folgenden kodierten Strings: http%3A/Joreilly .com httP%3A/J burningbird%1CnetJindex. php%3Fpagename%3D%141%26page%3D%241 Dabei werden Leerzeichen, Doppelpunkte, Schrägstriche und andere Zeichen kodiert, die in einem HTML-Kontext eine Bedeutung besitzen. Um den String wieder zurückzu verwandeln, verwenden Sie die Funktion unescape. Die Funktion escape ist zwar praktisch, hat aber Probleme bei Nicht-ASCII-Zeichen. Es gibt allerdings zwei Funktionen - encodeURI und decodeURI - die eine Kodierung auch über den ASCII-Zeichensatz hinaus vornehmen. Dabei werden alle Zeichen kodiert, mit Ausnahme der in Tabelle 2-4 aufgeführten (aus der »Mozilla Core JavaScript 1.5 Refe rence« übernommen).
TabeUe 2-4: Zeic!lell, die bei der UR1-Kodierung beibehalteIl werden Typ
Beinhaltet
Rl'SE'rvierte Zeichen
;,!?:@&=+5
Nicht kodierte Zeichen
Buchstaben, Ziffern, - _ . ! - " ( )
Ziffemzeichen
•
Wenn der Body des JavaScript-Blocks in Beispiel 2-1 durch das Folgende ersetzt wird: var sURL "http://oreilly.com/this_is_a_value&some-value_' some value ' " j sURL _ encodeURI(sURL); document.writeln("(p>" + sURL + "(/p>")j •
sieht das Ergebnis so aus: http://oreilly.com/this_is_a_value&some-value_' some%2ovalue' Die Funktion decodeURI kann genutzt werden, um den ursprünglichen, unkodierten String zu erhalten. Es gibt noch zwei weitere Funktionen zum Kodieren von URls - encodeURIComponent und decodeURIComponent -, die im Zusammenhang mit Ajax verwendet werden, weil sie auch &, + und " kodieren. Diese werden in Kapitel 13 behandelt. Sie können auch Unicode-Zeichen in einem String aufnehmen, indem Sie dem viersteI ligen hexadezimalen Wert des Zeichens ein \u voranstellen. So ergibt zum Beispiel das Folgende das chinesische (vereinfachte) Ideogramm für »Liebe«: document.writeln("\u7131"); Was angezeigt wird, ist mehr oder weniger browserabhängig. Aber die meisten der be kannteren Browser haben heutzutage eine ausreichende Unicode-Unterstützung. Mehr über Unicooe und die wichtigsten übersichtstabellen finden Sie unter
hup://www.unicode.org/.
Einfache Typen
I 39
Der leere String ist ein besonderer Fall, er wird im Allgemeinen genutzt, um eine Variable vom Typ string zu initialisieren, wenn sie definiert wurde. Die folgenden beiden Zeilen sind Beispiele für leere Strings: var string_value _ " ; var string_value _ " " i Es
ist für die JavaScript-Engine egal, welche Anführungszeichen Sie verwen den. Wichtig ist nur, dass Sie die gewählten dann konsequent nutzen.
All dies sind Beispiele dafür, wie man explizit eine String-Variable erstellt und was für Möglichkeiten es bei String-Literalen mit Sonderzeichen gibt. Die Werte in einer Variab len können auch je nach Kontext aus anderen Datentypen konvertiert werden. Wenn eine numerische oder Boolesche Variable einer Funktion übergeben wird, die einen String erwartet, wird der Wert zunächst implizit in einen String konvertiert, bevor er ver arbeitet wird: var num_value 35.00; alert(num_value); -
Werden dann weitere Variablen addiert, werden abhängig vom Kontext Nicht-String Variablen ebenfalls in Strings konvertiert. Sie haben das schon gesehen, als Nicht-String Werte einem String hinzugefügt (angehängt) wurden, um ihn dann in einem Dialogfens ter auszugeben: Va! num value 35.00; var string_value _ "Dies ist eine Zahl: "
"
+ num_value;
Sie können auch eine Variable explizit in einen String konvertieren, indem Sie String nutzen (toString in ECMAScript). Wenn der zu konvertierende Wert ein Boolescher Wert ist, ist das Ergebnis eine textuelle Darstellung dieses Werts: "true" für true und "false" für false. Bei Zahlen ist der String eine Textdarstellung der Zahl, wie zum Beispiel "-123.06" für -123,06 (abhängig von der Anzahl der Stellen und der Genauigkeit, also der Position des Dezimalpunkts) . Ein Wert von NaN (Not a Number, siehe weiter unten) liefert "NaN" zurück. Tabelle 2-5 zeigt die Ergebnisse bei der Verwendung von toString für verschiedene Da tentypen.
Tabel/e 2-5: Umwandlungs/abel/ell fii.r loS/ring Eingabe
Ergebnis
Undefined
"undefined"
Null
"null"
Boolean
wenn true, dann "true"; wenn talS!', dann "false"
4() I
Kapitel l: Datentypen und Variablen
Tabelle 2-5: Umwandlungs/abeUen für loS/ring (For/se/zwlg) Eingabe
Ergebnis
Number
siehe Text
String
keilll' Umwandlung
Object
eine textuelle Darstellung der Stand.lrddarstel lung des Objekts
Der letzte Eintrag in Tabelle 2-5 beschreibt, wie eine String-Umwandlung bei einem Ob jekt funktioniert_ Innerhalb der ECMAScript-Spezifikation ruft die Umwandlungsroutine zuerst die Funktion toPrimitive auf, bevor die Typkonvenierung durchgeführt wird. Die Funktion toPrimitive ruft, sofern vorhanden, die Objektmethode OefaultValue auf und gibt das Ergebnis zurück. So liefert zum Beispiel toString beim Objekt window in manchen Browsern den folgenden Wert zurück: [object lOindowJ Das kann nützlich sein, wenn Sie beim Debuggen den Wert einer Variablen erhalten wol len.
Der Datentyp Boolean Der Datentyp boolean hat zwei mögliche Werte: true und false. Sie sind nicht von Anführungszeichen umschlossen, mit anderen Worten: "false" ist nicht das Gleiche wie
false. Die Funktion Boolean (ToBoolean in ECMAScript) kann andere Werte zu einem Boole schen true oder false umwandeln, siehe auch Tabelle 2-6.
Tabelle 2-6: Umwandlungs/abeUe für ToBooleml Eingabe
Ergebnis
Undefined
false
Null
false
Boolean
WeftYOO value
Number
false, Wffin number O oder NaN ist; ansonsten true
String
false, wenn string leer ist; ansonstffi true
Object
true
Der Datentyp Number Zahlen in JavaScript sind Gleitkommazahlen, aber der Nachkommaanteil ist keine Pflicht. Wenn sie keinen Dezimalpunkt haben, werden sie als Integer-Werte behandelt - ganze Dezimalzahlen in einem Bereich von _253 bis 253. Die folgenden Werte sind gültige Inte ger-Zahlen:
Einfache Typen I 41
-""'" o
1534 Die Glcitkommadarstcllung hat einen Dezimalpunkt und eine Nachkommakomponente. Sie kann auch mit einem Exponenten dargestellt werden, wobei dieser in der E-Notation angegeben ist. Alle folgenden Zahlen sind gültige Gleitkommazahlenl: 0.3555 144.006 19.5('-1 (das entspricht 19,5* 10-2) Auch wenn große Zahlen unterstützt werden, können manche Funktionen nur im Be reich von -2e3 1 bis 2e31 (-2.147.483.648 bis 2.147.483.648) arbeiten, daher sollten Sie Ihre Zahlen auf diesen Bereich beschränken. Es gibt zwei spezielle Zahlen: positives und negatives Unendlich. In JavaScript werden sie durch Infinity und -Infinity dargestellt. Ein positives Unendlich wird zurückgegeben, wenn in einer JS-Anwendung ein Zahlen überlauf stattfindet. Neben der Dezimaldarstellung können auch oktale und hexadezimale Notationen genutzt werden, wobei die Oktaldarstellung aber nicht mehr venvendet werden sollte, da sie im Standard als veraltet (deprecated) gekennzeichnet ist. Eine Hexadezimalzahl beginnt mit einer Null, gefolgt von einem x: -OxCCFF Oktale Werte beginnen mit Nullen und ohne x: 0516 Sie können Strings oder Boolesche Werte in Zahlen konvertieren. Dabei helfen beim Um wandeln die beiden Funktionen parseInt und parseFloat je nach Art der Zahl, die Sie zu rückgeben wollen. Die Funktion parseInt liefert den ganzzahligen Anteil einer Zahl in einem String zurück, unabhängig davon, ob der String eine Integer- oder Gleitkommazahl enthält Die Funk tion parseFloat liefert den Gleitkommawert bis zu der Stelle zurück, an der ein nicht nu merisches Zeichen erreicht wird. In Beispiel 2-3 werden drei Strings mit numerischen Werten an parseInt oder parseFloat übergeben und die Werte ausgegeben.
Beispiel 2·3: Strings mit verschiedenen Funktionell in Zahlen umwandeln < IOOCTYPE html PUBLIC "-/IW3C//DTO XHTML 1.0 Transitional//EN" "http: //www.w3.org/TR/xhtm11/ DTO/xhtmll-transitional.dtd">
In Javaxripl wird - wie in den meisten Programmiersprachen - ein Dezimalpunkl Slall des im deulSChsprachi· gen Raum oblichen De2imalkommas genutzt. Die Zahl1 23 ,45 schreibt sich inJavaScript also als1 23 .4 5 .
42
I
Kapitel l: Datentypen und Variablen
Beispiel 2-3: Strillgs mir versclliedellen FUllktiOllel1 in Zahlen umwandeln (FortsetzlIIlg) Strings in Zahlen umwandlen <meta http-equiv_"Content_Type" content_"text/htmlj charset-utf-8" I> ' p' <script type_"text/javascript"> 11<1 [CDATA[ var sNum - "1.23e-l"j document.writeln (parseFloat(sNum» j var fValue _ parseFloat("1.45cm") j document.writeln ("" + fValue + "
")j var iValue parselnt("33.00")j document.writeln ("" + iValue •
+
"
")j
11][>