Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Geleitwort des Fachgutachters
Vorwort
1 Einführung
2 Mathematische und technische Grundlagen
3 Hardware
4 Netzwerkgrundlagen
5 Betriebssystemgrundlagen
6 Windows
7 Linux
8 Mac OS X
9 Grundlagen der Programmierung
10 Konzepte der Programmierung
11 Software-Engineering
12 Datenbanken
13 Server für Webanwendungen
14 Weitere Internet-Serverdienste
15 XML
16 Weitere Datei- und Datenformate
17 Webseitenerstellung mit (X)HTML und CSS
18 Webserveranwendungen
19 JavaScript und Ajax
20 Computer- und Netzwerksicherheit
A Glossar
B Zweisprachige Wortliste
C Kommentiertes Literatur- und Linkverzeichnis
Stichwort

Download:
- ZIP, ca. 26,3 MB
Buch bestellen
Ihre Meinung?

Spacer
IT-Handbuch für Fachinformatiker von Sascha Kersken
Der Ausbildungsbegleiter
Buch: IT-Handbuch für Fachinformatiker

IT-Handbuch für Fachinformatiker
Galileo Computing
ca. 1172 S., 5., aktualisierte und erweiterte Auflage, geb.
ca. 34,90 Euro, ISBN 978-3-8362-1744-6
Pfeil 19 JavaScript und Ajax
Pfeil 19.1 JavaScript
Pfeil 19.2 JavaScript im HTML-Dokument
Pfeil 19.2.1 Erstes Beispiel: Ausgabe ins Dokument
Pfeil 19.3 Formulare und Event Handler
Pfeil 19.3.1 Erstes Beispiel
Pfeil 19.3.2 Zugriff auf Formulare und ihre Elemente
Pfeil 19.4 Datums- und Uhrzeit-Funktionen
Pfeil 19.4.1 Datums- und Uhrzeit-Methoden
Pfeil 19.4.2 Timeout – die JavaScript-»Stoppuhr«
Pfeil 19.5 Manipulation von Bildern
Pfeil 19.5.1 Erstes Beispiel: Austauschen eines Bildes auf Knopfdruck
Pfeil 19.5.2 Vorausladen von Bildern
Pfeil 19.5.3 Eine gut funktionierende Rollover-Lösung
Pfeil 19.6 Browser- und Fensteroptionen
Pfeil 19.6.1 Browser-Eigenschaften
Pfeil 19.6.2 Automatische Hyperlinks – History und Location
Pfeil 19.6.3 Neue Browserfenster öffnen
Pfeil 19.7 DHTML und DOM
Pfeil 19.7.1 W3C-DOM im Überblick
Pfeil 19.7.2 Eine DOM-Baum-Anzeige
Pfeil 19.7.3 DOM-Anwendung in der Praxis
Pfeil 19.7.4 Dokumentinhalte verändern und austauschen
Pfeil 19.8 Ajax
Pfeil 19.8.1 Die erste Ajax-Anwendung
Pfeil 19.8.2 Datenaustauschformate: XML und JSON
Pfeil 19.8.3 Größeres Beispiel: eine interaktive Länderliste
Pfeil 19.9 Zusammenfassung

Galileo Computing - Zum Seitenanfang

19.3 Formulare und Event HandlerZur nächsten Überschrift

Die Ein- und Ausgabe über prompt()-Boxen und das Schreiben in das Dokument sind zwar zum Erlernen von Operatoren und Ausdrücken hilfreich, entsprechen aber ansonsten nicht der üblichen Arbeit mit JavaScript. prompt() sollte nur für Test- und Debugging-Zwecke eingesetzt werden, genau wie seine beiden Kollegen alert() (nur Ausgabe in einer Box mit OK-Button) und confirm() (Ausgabe mit Auswahl zwischen OK- und Abbrechen-Button), die true beziehungsweise false zurückgeben.

Im »richtigen Leben« werden in der Regel HTML-Formulare zur Ein- und Ausgabe verwendet.

Event Handler

Das einzige Problem besteht darin, dass Skripts aus Formularen heraus explizit aktiviert werden müssen. Die bisherigen Beispiele mit den prompt()-Boxen liefen automatisch beim Dokumentaufruf ab, ein Formular steht dagegen die ganze Zeit auf der Seite zur Verfügung, und Benutzer müssen entscheiden können, wann sie das entsprechende Skript aufrufen möchten. Dazu werden sogenannte Event Handler (etwa »Ereignisverarbeiter«) verwendet: Formal gesehen handelt es sich bei ihnen um HTML-Attribute, die jedoch den speziellen Zweck haben, JavaScript-Code auszuführen, der ihren Parameterwert bildet.


Galileo Computing - Zum Seitenanfang

19.3.1 Erstes BeispielZur nächsten ÜberschriftZur vorigen Überschrift

Hier zunächst ein kleines Beispieldokument, das beides verwendet:

<html>
<head>
<title>Erster Formulartest</title>
</head>
<body>
<h1>Der Gruß-o-Mat</h1>
<form name="formular">
Dein Name.:
<input type="text" name="user" size="40" />
<input type="button" value="OK"
onclick="document.formular.gruss.value = 'Hallo '
+ document.formular.user.value + '!';" />
<br />
<input type="text" name="gruss" size="60"
readonly="readonly" />
</form>
</body>
</html>

Dazu sind einige Erläuterungen erforderlich:

  • Diejenigen Formularelemente, auf die JavaScript zugreift, erhalten bequemerweise jeweils einen Namen (das Attribut name). Das Formular selbst heißt formular; die beiden Textfelder heißen user für die Eingabe (bitte niemals name verwenden, da dieses Wort in JavaScript eine feste Bedeutung besitzt) und gruss für die Ausgabe.
  • Das Ausgabefeld gruss besitzt die spezielle Eigenschaft »schreibgeschützt«, die durch das Attribut readonly="readonly" eingerichtet wird. Die klassische Schreibweise ist readonly ohne Parameterwert. Da das vorliegende HTML-Dokument jedoch in XHTML geschrieben ist, wird formal ein Wert für das Attribut benötigt.
  • Der Button (das <input>-Tag mit dem Attribut type="button", also allgemeiner Button) besitzt einen Event Handler. onclick="..." führt die als Wert übergebenen JavaScript-Anweisungen aus, sobald der Button angeklickt wird, in dem der Event Handler steht. Formal gesehen ist onclick (und jeder andere Event Handler) ein HTML-Attribut, deshalb gelten die entsprechenden Regeln: Zwischen onclick, dem Gleichheitszeichen und dem beginnenden Anführungszeichen darf kein Leerzeichen stehen. Innerhalb der Anführungszeichen des Attributwerts gilt dagegen die JavaScript-Syntax – mit einer Ausnahme: Es dürfen nur einfache Anführungszeichen (') verwendet werden! Ein doppeltes Anführungszeichen würde sonst vom Browser als Ende des HTML-Attributs erkannt. Auch \" funktioniert nicht, weil HTML diese Schreibweise nicht kennt.
  • Die eigentliche JavaScript-Anweisung, also der Wert des Attributs onclick, ist folgende:
document.formular.gruss.value =
'Hallo ' + document.formular.user.value + '!';

Es wird auf das Unterobjekt gruss (das Textfeld) des Unterobjekts formular (das Formular) des Dokument-Objekts zugegriffen, und zwar auf dessen Eigenschaft value – es handelt sich um den Wert oder genauer den Inhalt des Textfelds. Auf dieselbe Weise erfolgt der Zugriff auf den Wert oder Inhalt des Textfelds user, das heißt auf die Benutzereingabe. Durch die Wertzuweisung wird der passende Gruß in das Ausgabefeld geschrieben.


Galileo Computing - Zum Seitenanfang

19.3.2 Zugriff auf Formulare und ihre ElementeZur nächsten ÜberschriftZur vorigen Überschrift

Grundsätzlich befinden sich alle Formulare einer Seite, das heißt alle <form>...</form>-Bereiche, in einem Objekt-Array namens document.forms[]: Das erste Formular auf einer Seite ist document.forms[0], das zweite document.forms[1] und so weiter.

Wird einem Formular (wie im Beispiel oben) ein Name zugewiesen, so erfolgt der Zugriff komfortabler: Das Formular kann entweder einfach als

document.Formularname

angesprochen werden – dazu muss der Formularname aber auf jeden Fall den formalen Regeln für JavaScript-Bezeichner entsprechen –, oder aber es wird mittels

document.forms["Formularname"]

der Name (statt der Nummer) als String-Index verwendet. Jedes JavaScript-Array kann – wie in PHP – numerisches Array und Hash in einem sein. Natürlich bleibt auch nach einer Namensvergabe der Zugriff über die Nummer möglich.

Formularelemente

Auf dieselbe Weise werden alle Elemente eines Formulars als document.Formular.elements[] in einem Array zusammengefasst. Elemente sind alle Textfelder, Textbereiche, Auswahlfelder, Radiobutton-Gruppen, Checkbox-Gruppen, Buttons und Hidden-Felder in derjenigen Reihenfolge, in der sie im HTML-Dokument definiert wurden.

Falls ein Element einen Namen besitzt (das Attribut name), kann dieser wieder als Objektbezeichner (document.Formular.Elementname) oder als Hash-Index (document.Formular .elements["Elementname"]) verwendet werden.

Nehmen Sie zum Beispiel an, das erste Formular in einem HTML-Dokument sähe folgendermaßen aus:

<form name="test">
<input type="text" name="eingabe" />
<input type="button" value="OK" />
</form>

Alle Zugriffsarten

Dann kann der Zugriff auf das Textfeld eingabe auf unterschiedliche Weise erfolgen:

document.forms[0].elements[0]
document.forms[0].elements["eingabe"]
document.forms[0].eingabe

document.forms["test"].elements[0]
document.forms["test"].elements["eingabe"]
document.forms["test"].eingabe

document.test.elements[0]
document.test.elements["eingabe"]
document.test.eingabe

Sie können also den numerischen Zugriff, die Objektnamen und die Hash-Indizes beliebig mischen.

Kleiner Rechner mit einem Formular

Da es ziemlich wartungsunfreundlich und unübersichtlich wäre, größere Codemengen direkt in einen Event Handler zu schreiben, ist es empfehlenswert, stattdessen in einem Skript im Head des Dokuments Funktionen zu definieren und diese dann über die Event Handler aufzurufen.

Im Folgenden wird ein kleiner formularbasierter Taschenrechner vorgestellt. Sie können zwei Zahlen eingeben und durch Anklicken der gewünschten Operation das Ergebnis ermitteln.

Funktionen

Die Syntax für JavaScript-Funktionen ist mit der im vorigen Kapitel beschriebenen PHP-Funktionssyntax identisch: Auf das Schlüsselwort function folgt der Bezeichner der Funktion, anschließend steht in Klammern die (möglicherweise leere) Parameterliste. Den Rumpf der Funktion bildet schließlich ein Block, also ein Bereich in geschweiften Klammern.

Für das Rechner-Beispiel wird zunächst in einem <script>-Block im Head die folgende Funktion definiert:

function rechnen (op) {
// Eingaben lesen
var z1 = document.rechner.z1.value;
var z2 = document.rechner.z2.value;
// Sind es keine Zahlen?
if (z1 != parseFloat (z1) || z2 != parseFloat (z2)) {
// Mindestens eine ist keine Zahl!
document.rechner.erg.value = "Keine Zahl!";
// Rücksprung aus der Funktion heraus
return;
}
// Wenn wir HIER sind, waren es Zahlen!
var erg;
switch (op) {
case "+":
erg = parseFloat (z1) + parseFloat (z2);
break;
case "-":
erg = z1 - z2;
break;
case "*":
erg = z1 * z2;
break;
case "/":
if (z2 == 0)
erg = "0 VERBOTEN!";
else
erg = z1 / z2;
break;
default:
erg = "KANN NICHT SEIN!";
}
document.rechner.erg.value = erg;
}

Das Formular mit den Eingabefeldern und den Buttons zum Aufrufen dieser Funktion im Body sieht dann so aus:

<form name="rechner">
1. Zahl:
<input type="text" name="z1" size="20" />
2. Zahl:
<input type="text" name="z2" size="20" />
<br />
<input type="button" value=" + "
onclick="rechnen ('+');" />
<input type="button" value=" - "
onclick="rechnen ('-');" />
<input type="button" value=" * "
onclick="rechnen ('*');" />
<input type="button" value=" / "
onclick="rechnen ('/');" />
<br />
<input type="text" name="erg" size="40"
readonly="true" />
</form>

Formularauswertung

Es ist eine praktische Angelegenheit, HTML-Formulare schon vor dem Absenden direkt im Browser per JavaScript ein wenig auf Plausibilität zu überprüfen: Sind alle Pflichtfelder ausgefüllt? Haben bestimmte Felder Werte, die gewisse formale Kriterien erfüllen (zum Beispiel Postleitzahlen oder E-Mail-Adressen)? Die wichtigsten Möglichkeiten bieten die eingebauten String-Methoden sowie reguläre Ausdrücke. Beide werden im Folgenden vorgestellt.

String-Methoden

Jeder String-Ausdruck kann in JavaScript als Objekt betrachtet werden, und eine Reihe von Methoden können zum Zugriff auf dieses Objekt angewandt werden:

  • Die Eigenschaft String.length gibt die Länge eines Strings in Zeichen an. Beispiele:
  • JavaScript".length  // liefert 10
    "".length // liefert 0

  • String.charAt (Pos) liefert das Zeichen eines Strings an der Position Nummer Pos. Die erste Position ist 0, die letzte ist String.length1. Beispiel:
  • "JavaScript".charAt(4)  // liefert "S"

  • String.substring (Anf_Pos, End_Pos) gibt den Teilstring eines Strings an, beginnend mit dem Zeichen an der Position Anf_Pos (ab 0) bis vor das Zeichen End_Pos: Die Angabe End_Pos gibt das erste Zeichen an, das nicht mehr vorkommen soll (»bis ausschließlich ...«). Beispiele:
  • "JavaScript macht Spass".substring(11, 16)
    // liefert "macht"
    "Java aber noch mehr!".substring(0, 5)
    // liefert "Java"
    var text = "Hallo liebe Welt!";
    text.substring(text.length - 4, text.length)
    // liefert "Welt!"

  • String.indexOf (Teilstring) gibt die erste Position (ab 0) an, an der Teilstring in einem String beginnt, oder –1, wenn Teilstring gar nicht im String vorkommt. Beispiele:
  • "javascript".indexOf("ja")           // liefert 0
    "javascript".indexOf("nein") // liefert -1
    "in den Rhein hinein".indexOf("ein") // liefert 9

  • String.lastIndexOf (Teilstring) gibt die letzte Position (ab 0) an, an der Teilstring im String beginnt, oder –1, wenn Teilstring nicht im String vorkommt. Beispiele:
  • "in den Rhein hinein".lastIndexOf("in")  // 17
    "javascript".lastIndexOf("no") // -1

Hier zwei Beispiele zur Untersuchung von Eingaben mit diesen Methoden:

  1. Untersuchung einer E-Mail-Adresse
    Die Variable mail sei der Inhalt eines Texteingabefeldes. Der Inhalt soll daraufhin überprüft werden, ob es sich formal um eine E-Mail-Adresse handeln kann. Der folgende Codeblock führt entsprechende Tests durch:
  2. // Annahme: E-Mail ist gültig:
    var mailOK = true;
    // E-Mail-Adresse vorhanden?
    if (!mail) {
    mailOK = false;
    }
    // "@"-Zeichen überhaupt vorhanden?
    if (mail.indexOf("@") == -1) {
    mailOK = false;
    }
    // "@"-Zeichen am ANFANG oder am ENDE?

    if (mail.indexOf("@") == 0 ||
    mail.lastIndexOf("@") == mail.length - 1) {
    mailOK = false;
    }
    // MEHR als ein "@"-Zeichen?
    if (mail.indexOf("@") != mail.lastIndexOf("@")) {
    mailOK = false;
    }
    if (!mailOK) {
    alert ("E-Mail-Adresse ungültig!");
    }// Annahme: PLZ gültig!
    var plzOK = true;
    // PLZ zu lang oder zu kurz?
    if (plz.length != 5) {
    plzOK = false;
    } else {
    for (i = 0; i < 5; i++) {
    if (plz.charAt(i) < "0" || plz.charAt(i) > "9") {
    plzOK = false;
    }
    }
    }
    if (!plzOK) {
    alert("Postleitzahl inakzeptabel!");
    }

  3. Untersuchung einer Postleitzahl
    Die Variable plz soll daraufhin untersucht werden, ob sie eine gültige deutsche Postleitzahl enthält (fünf Stellen, nur Ziffern):
  4. // Annahme: PLZ gültig!
    var plzOK = true;
    // PLZ zu lang oder zu kurz?
    if (plz.length != 5) {
    plzOK = false;
    } else {
    for (i = 0; i < 5; i++) {
    if (plz.charAt(i) < "0" || plz.charAt(i) > "9") {
    plzOK = false;
    }
    }
    }
    if (!plzOK) {
    alert("Postleitzahl inakzeptabel!");
    }

Den Eingabefokus setzen

Eine benutzerfreundliche Erweiterung kann übrigens darin bestehen, den Cursor bei der Formularüberprüfung automatisch in das Textfeld zu setzen, in dem der erste Fehler gefunden wurde. Schematisch funktioniert das folgendermaßen:

document.Formular.Element.focus();

Hier die konkrete Schreibweise für ein Feld namens kunde im Formular bestell:

document.bestell.kunde.focus();

Reguläre Ausdrücke

Die Syntax für reguläre Ausdrücke in JavaScript wurde aus Perl übernommen (siehe Kapitel 10, »Konzepte der Programmierung«). Ihre Verwendung funktioniert allerdings anders.

Wie in Perl stehen RegExp-Konstrukte auch in JavaScript nicht in Anführungszeichen, sondern zwischen zwei /-Zeichen:

/RegExp/

Als Erstes sehen Sie hier die einfachste JavaScript-Form für den Einsatz regulärer Ausdrücke: Die Methode

String.match(/RegExp/)

gibt true zurück, wenn der String dem Muster RegExp entspricht, ansonsten false.

Auf diese Weise lässt sich zum Beispiel die Postleitzahl viel schneller und einfacher überprüfen:

var plz = document.bestell.plz.value;
if (!plz.match(/^\d{5}$/) {
alert ("Dies ist keine gueltige PLZ!");
}

Der reguläre Ausdruck /^\d{5}$/ trifft auf genau fünf beliebige Ziffern zu, beschreibt also eine deutsche Postleitzahl.

Auch der Test der E-Mail-Adresse beschränkt sich nun auf die folgende Kurzfassung:

if (!mail.match(/^[^\@]+\@[^\@]+$/)) {
alert ("E-Mail-Adresse ungueltig!");
}

Selbst für Namen ließe sich eine Art Plausibilitätskontrolle durchführen: Der Ausdruck /[^\s]+\s+[^\s]+/ verlangt mindestens zwei Blöcke von Zeichen (»Nicht-Leerzeichen«), die durch mindestens ein Whitespace-Element voneinander getrennt sind.

Für die Auswertung einer Namenseingabe mit der Bezeichnung kunde könnte folgender Code verwendet werden:

if (!kunde.match(/[^\s]+\s+[^\s]+/)) {
alert ("Bitte VOR- und NACHNAMEN angeben!");
}

Fortgeschrittene RegExp-Beispiele

Um die Verwendung regulärer Ausdrücke in JavaScript zu verdeutlichen, folgen noch einige praktische Beispiele.

In Webforen, Gästebüchern oder ähnlichen Anwendungen besteht theoretisch die Möglichkeit, HTML-Code einzugeben und damit den Browsern der anderen Benutzer unterzuschieben. Im Extremfall schreibt jemand so etwas wie:

<script language="JavaScript" type="text/javascript">
window.location.href="http://meinewerbung.com";
</script>

Durch diesen Code erfolgt sofort ein Sprung zur angegebenen Seite (solche »automatischen Hyperlinks« werden im Abschnitt »Automatische Hyperlinks – History und Location« ab Seite 1020 erläutert); das Forum/Gästebuch ist damit ausgeschaltet!

HTML-Tags entfernen

Insofern ist es für solche Anwendungen wünschenswert, gar keine HTML-Tags zuzulassen oder sie zumindest auf harmlose Textformatierungs-Tags zu beschränken.

Finden lassen sich HTML-Tags in Strings relativ leicht durch den folgenden Ausdruck:

/<[^>]+>/

Das Problem ist, dass in einer Zeile mehrere HTML-Tags vorkommen können – dieser Ausdruck findet nur das erste von ihnen. Darüber hinaus genügt das Finden allein noch nicht, um den schädlichen Code durch harmlosen zu ersetzen.

Für Letzteres wird statt der Methode String.match() die Methode String.replace() verwendet, die einen regulären Ausdruck findet und an dessen Stelle einen beliebigen String setzt. Beispielsweise ersetzt

eingabe = eingabe.replace(/<[^>]+>/, "");

den ersten <>-Ausdruck im String eingabe durch gar nichts.

Das zweite Problem – das Finden und Ersetzen aller derartigen Ausdrücke im String und nicht bloß des ersten – funktioniert wie in Perl mit Hilfe des Modifizierers /g (für »global«). Die korrekte Form der Anweisung lautet also allgemein so:

String.replace(/RegExp1/g, String2);

Im HTML-Tag-Beispiel müssen Sie also Folgendes schreiben:

eingabe = eingabe.replace(/<[^>]+>/g, "");

Treffer-Variablen

Wie in Perl können bestimmte Teile der durch reguläre Ausdrücke gefundenen Treffer im Ersetzungs-String verwendet werden: Jeder Teil eines regulären Ausdrucks, der in runde Klammern gesetzt wird, wird bei einem Treffer in einer automatischen Eigenschaft namens $1 bis $9 abgelegt – es sind mit anderen Worten neun Speicherplätze möglich.

Es handelt sich um Eigenschaften des globalen Objekts RegExp, sie werden also als RegExp.$1 bis RegExp.$9 angesprochen. Sie können im Ersetzungs-String durch das übliche + verkettet werden. Leider stehen sie ausgerechnet in der Methode replace() nicht zur Verfügung; stattdessen müssen Sie ein RegExp-Objekt konstruieren und dessen Methode exec() ausführen. Hier ein kleines Beispiel:

In der Variablen kunde stehen Vor- und Nachname eines Kunden in der Form »Larry Wall«. Diese beiden Bestandteile sollen vertauscht und somit in »Wall, Larry« geändert werden. Dies funktioniert folgendermaßen:

var muster = /([^\s]+)\s+([^\s]+)/;
muster.exec(kunde);
kunde = RegExp.$2 + ", " + RegExp.$1;

([^\s]+) beschreibt ein oder mehrere Nicht-Leerzeichen, die durch die runden Klammern in RegExp.$1 gespeichert werden. \s+ steht für beliebig viel Whitespace; darauf folgt der zweite Klammerausdruck ([^\s]+), der wiederum ein oder mehrere Nicht-Leerzeichen beschreibt und in RegExp.$2 abgelegt wird.



Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.







<< zurück




Copyright © Galileo Press 2011
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Galileo Computing]

Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de


  Zum Katalog
Zum Katalog: IT-Handbuch für Fachinformatiker






IT-Handbuch für Fachinformatiker
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchempfehlungen
Zum Katalog: Java ist auch eine Insel






 Java ist auch
 eine Insel


Zum Katalog: Android 3






 Android 3


Zum Katalog: Linux






 Linux


Zum Katalog: Ubuntu GNU/Linux






 Ubuntu
 GNU/Linux


Zum Katalog: Windows Server 2008 R2






 Windows Server
 2008 R2


Zum Katalog: PHP & MySQL






 PHP & MySQL


Zum Katalog: Visual C# 2010






 Visual C# 2010


Zum Katalog: C von A bis Z






 C von A bis Z


Zum Katalog: C++ von A bis Z






 C++ von A bis Z


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo