JavaScript-Basics

JavaScript ist eine clientseitige Skriptsprache, die hauptsächlich für die Webentwicklung verwendet wird. Im Gegensatz zu serverseitigen Sprachen wie PHP wird JavaScript direkt im Browser des Benutzers ausgeführt und ermöglicht interaktive und dynamische Webseiten.

Hinweis

Diese Lernunterlage basiert auf den Kursinhalten und den durchgemachten Übungsbeispielen. Sie deckt die grundlegenden Konzepte von JavaScript ab.

Hauptmerkmale von JavaScript

  • Clientseitige Sprache (wird im Browser ausgeführt)
  • Dynamisch typisiert (Variablen benötigen keine explizite Typdeklaration)
  • Objektorientiert und ereignisgesteuert
  • Ermöglicht DOM-Manipulation (Document Object Model)
  • Kann in HTML-Dateien eingebettet oder als externe Datei eingebunden werden

Anwendungsbereiche

  • Interaktive Webseiten erstellen
  • Formularvalidierung
  • Dynamische Inhalte nachladen (AJAX)
  • Animationen und visuelle Effekte
  • Single-Page-Applications (SPAs)
  • Serverseitige Entwicklung (Node.js)

Grundlegende JavaScript-Syntax

JavaScript-Code kann auf verschiedene Arten in eine HTML-Datei eingebunden werden:


<script>
    // Hier steht der JavaScript-Code
</script>

Oder als externe Datei:


<script src="meinscript.js"></script>

Wichtige Syntax-Regeln

  • Anweisungen enden mit einem Semikolon ;
  • JavaScript unterscheidet zwischen Groß- und Kleinschreibung
  • Kommentare werden mit // für einzeilige oder /* */ für mehrzeilige Kommentare gekennzeichnet

Variablen und Datentypen

Variablendeklaration

In JavaScript können Variablen mit let, const oder var (veraltet) deklariert werden:


// Variablendeklaration mit let
let a = 17, b = 23, c;
c = a + b;

// Konstanten mit const (Wert kann nicht geändert werden)
const PI = 3.14159;

// Variablendeklaration mit var (ältere Methode)
var name = "Max";
Wichtig

Die Verwendung von var sollte vermieden werden, da es zu unerwarteten Verhaltensweisen führen kann. Verwende stattdessen let für veränderliche Variablen und const für Konstanten.

Beispiel aus 07_js_variablen.html:


let a = 17, b = 23, c;
c = a + b;
console.log(c); // Ausgabe: 40

Datentypen in JavaScript

JavaScript kennt folgende grundlegende Datentypen:

  • Number: Ganze Zahlen und Gleitkommazahlen
  • String: Texte und Zeichenketten
  • Boolean: Wahrheitswerte ( true oder false)
  • Object: Komplexe Datenstrukturen
  • Array: Geordnete Listen (technisch gesehen ein Objekt)
  • Undefined: Eine Variable ohne zugewiesenen Wert
  • Null: Ein leerer oder nicht existierender Wert

Ausgabemethoden

JavaScript bietet verschiedene Methoden, um Inhalte auszugeben:


// Ausgabe in der Entwicklerkonsole
console.log("Hallo Welt");
console.log(c); // Ausgabe einer Variable
console.log("Der Inhalt von c ist:", c); // Mehrere Werte ausgeben

// Alert-Box anzeigen
alert("Der Wert von c ist: " + c);

// Bestätigungsdialog anzeigen
let entscheidung = confirm("Wollen Sie das wirklich tun?");
console.log("entscheidung=", entscheidung);

// Eingabeaufforderung anzeigen
let vn = prompt("Bitte geben Sie Ihren Vornamen ein:");
console.log("Der eingegebene Vorname war:", vn);

// Ausgabe im HTML-Dokument
document.write('

Der eingegebene Vorname ist: ' + vn + '

');
Achtung

Die Verwendung von document.write() nach dem Laden einer Seite überschreibt den gesamten Inhalt. Verwende diese Methode daher mit Vorsicht.

Bedingungen und Verzweigungen

if/else Bedingungen

Mit if-Anweisungen können Entscheidungen basierend auf Bedingungen getroffen werden:


let z = Math.random(); // Zufallszahl zwischen 0 und 1

if(z > 0.5) {
    console.log("z ist größer als 0.5:", z);
} else {
    console.log("z ist kleiner-gleich 0.5:", z);
}

Mehrfache Bedingungen können mit else if verknüpft werden:


let vn = prompt("Bitte gib Deinen Vornamen ein:");

if(vn == "Alex") {
    console.log("Hallo Alexander");
} else if(vn == "Sabine") {
    console.log("Hi Sabine");
} else if(vn == "Thomas" || vn == "Tom") {
    console.log("Servus Tom");
} else {
    console.log("Hallo Unbekannte/r");
}

switch Anweisungen

Die switch-Anweisung bietet eine Alternative zu mehreren if/else-Blöcken:


let vn = prompt("Bitte gib Deinen Vornamen ein:");

switch(vn) {
    case "Alex":
        console.log("Hallo Alexander");
        break;
    
    case "Sabine":
        console.log("Hi Sabine");
        break;
        
    case "Thomas":
    case "Tom":
        console.log("Servus Tom");
        break;
        
    default:
        console.log("Hallo Unbekannte/r");
}
Hinweis

Das break-Statement ist wichtig, um nach einem passenden Case die Ausführung zu beenden. Ohne break würde die Ausführung in den nächsten Case-Block weiterlaufen.

Ein interessantes Beispiel für switch mit true:


let z2 = Math.random();

switch(true) {
    case z2 < 0.2:
        console.log("Sehr kleine Zahl", z2);
        break;
    
    case z2 < 0.5:
        console.log("Mittelgroße Zahl", z2);
        break;
        
    case z2 < 0.8:
        console.log("Größere Zahl", z2);
        break;
        
    default:
        console.log("Große Zahl", z2);
}

Schleifen

for Schleife

Die for-Schleife wird verwendet, wenn die Anzahl der Durchläufe bekannt ist:


for(let i = 0; i < 10; i++) {
    console.log("i=", i);
}

Beispiel mit Dekrementierung und Schrittweite:


for(let i = 25; i > -23; i -= 3.34) {
    console.log("i=", i);
}

while Schleife

Die while-Schleife wird verwendet, wenn die Anzahl der Durchläufe nicht im Voraus bekannt ist:


let z = Math.random();
console.log("(1) z=", z);

while(z < 0.5) {
    z = Math.random();
    console.log("(2) z=", z);
}

console.log("(3) z=", z);
Vorsicht vor Endlosschleifen

Bei while-Schleifen muss sichergestellt werden, dass die Bedingung irgendwann erfüllt wird, sonst entsteht eine Endlosschleife:


// Endlosschleife!
let z = 0.3;
while(z < 0.5) {
    console.log("z=", z);
    // z ändert sich nie, daher läuft die Schleife endlos
}

do-while Schleife

Die do-while-Schleife führt den Code mindestens einmal aus, bevor die Bedingung geprüft wird:


let z2;
do {
    z2 = Math.random();
    console.log("(2a) z2=", z2);
} while(z2 < 0.5);

console.log("(3a) z2=", z2);

Arrays

Array erstellen

Arrays sind geordnete Listen, die verschiedene Datentypen enthalten können:


// Array mit Literalschreibweise erstellen
let a = [];

// Array mit Konstruktorschreibweise erstellen
let b = new Array();

// Array mit initialisierten Werten
let farben = ["Rot", "Grün", "Blau"];

Array-Werte zuweisen:


let a = [];
a[0] = "Erster Eintrag";
a[1] = 42;
a[3] = 7; // Index 2 bleibt leer
console.log(a); // Ausgabe: ["Erster Eintrag", 42, undefined, 7]

Zugriff auf Arrays


let a = [];
a[3] = 7;
console.log(a[3]); // Ausgabe: 7

// Mit Variablen auf Arrays zugreifen
let x = 3;
console.log(a[x]); // Ausgabe: 7

Array-Iteration

Durchlaufen eines Arrays mit for-Schleife:


// Array vorwärts durchlaufen
for(let i = 0; i < a.length; i++) {
    console.log("a[" + i + "]=", a[i]);
}

// Array rückwärts durchlaufen
for(let i = a.length-1; i >= 0; i--) {
    console.log("a[" + i + "]=", a[i]);
}

// Jeden zweiten Eintrag ausgeben
for(let i = 0; i < a.length; i += 2) {
    console.log("a[" + i + "]=", a[i]);
}

Mehrdimensionale Arrays:


// Array mit Personen (Vor- und Nachname)
let personen = [];
personen[0] = ["Uwe", "Mutz"];
personen[1] = ["Silvia", "Mutz"];
personen[2] = ["Harald", "Maier"];
personen[3] = ["Ernst", "August"];

console.log(personen);

Array-Methoden

JavaScript bietet verschiedene Methoden, um Elemente zu Arrays hinzuzufügen oder zu entfernen:

Eselsbrücke zum Merken

Die Länge des Methodennamens entspricht der Auswirkung auf das Array:

  • pop() – kurzes Wort, macht das Array kürzer (entfernt Element am Ende)
  • push() – längeres Wort, macht das Array länger (fügt Element am Ende hinzu)

  • shift() – kurzes Wort, macht das Array kürzer (entfernt Element am Anfang)
  • unshift() – längeres Wort, macht das Array länger (fügt Element am Anfang hinzu)

Array-Methoden im Überblick


// Array erstellen
let zahlen = [1, 2, 3];
console.log(zahlen); // Ausgabe: [1, 2, 3]
                
// push() - fügt am ENDE hinzu (längeres Wort = Array wird länger)
zahlen.push(4);
console.log(zahlen); // Ausgabe: [1, 2, 3, 4]
                
// pop() - entfernt am ENDE (kürzeres Wort = Array wird kürzer)
let letzteZahl = zahlen.pop();
console.log(zahlen); // Ausgabe: [1, 2, 3]
console.log(letzteZahl); // Ausgabe: 4
                
// unshift() - fügt am ANFANG hinzu (längeres Wort = Array wird länger)
zahlen.unshift(0);
console.log(zahlen); // Ausgabe: [0, 1, 2, 3]
                
// shift() - entfernt am ANFANG (kürzeres Wort = Array wird kürzer)
let ersteZahl = zahlen.shift();
console.log(zahlen); // Ausgabe: [1, 2, 3]
console.log(ersteZahl); // Ausgabe: 0
                
// splice() - für Änderungen an BELIEBIGER Position
// splice(startIndex, anzahlZuEntfernen, elementeZumHinzufügen...)
zahlen.splice(1, 1); // Entferne 1 Element ab Index 1
console.log(zahlen); // Ausgabe: [1, 3]
                
zahlen.splice(1, 0, 2); // Füge das Element 2 an Index 1 ein
console.log(zahlen); // Ausgabe: [1, 2, 3]
                
zahlen.splice(1, 1, 4, 5); // Ersetze 1 Element ab Index 1 durch 4, 5
console.log(zahlen); // Ausgabe: [1, 4, 5, 3]
Wichtig

Die splice()-Methode ist vielseitiger als push(), pop(), shift() und unshift(), da sie an jeder Position im Array arbeiten kann. Sie kann Elemente entfernen, hinzufügen oder beides gleichzeitig tun.

Funktionen

Funktionsdeklaration

Funktionen sind wiederverwendbare Codeblöcke, die bestimmte Aufgaben ausführen. Sie können auf verschiedene Arten definiert werden:


// Funktionsdeklaration
function f0() {
    let a = 17, b = 23, c;
    c = a + b;
    console.log("f0: c=", c);
}
            
// Funktionsausdruck (anonyme Funktion)
let gruss = function() {
    console.log("Hallo Welt!");
};
            
// Sofort ausgeführte Funktion (IIFE)
(function() {
    console.log("Ich werde sofort ausgeführt!");
})();
            
// Funktionsaufruf
f0();
Hinweis

Funktionen, die mit der Funktionsdeklaration definiert werden, werden durch das "Hoisting" vor der eigentlichen Ausführung des Codes geladen und können daher vor ihrer Definition aufgerufen werden. Bei Funktionsausdrücken ist dies nicht möglich.

Parameter und Rückgabewerte

Funktionen mit Parametern nehmen Werte entgegen, die innerhalb der Funktion verwendet werden. Mit return können Funktionen Werte zurückgeben:


// Funktion mit Parametern, ohne Rückgabewert
function f1(a, b) {
    let c = a + b;
    console.log("f1: c=", c);
}
            
// Funktion ohne Parameter, mit Rückgabewert
function f2() {
    let a = 17, b = 23, c;
    c = a + b;
    console.log("f2: c=", c);
    return c;    // gibt den Wert zurück
}
            
// Funktion mit Parametern und Rückgabewert
function f3(a, b) {
    let c = a + b;
    console.log("f3: c=", c);
    return c;
}

Funktionsaufrufe mit Parametern und Rückgabewerten:


f1(17, 23); // Aufruf mit Übergabewerten, kein Rückgabewert
            
let ergebnis = f2(); // Rückgabewert wird in Variable gespeichert
console.log("ergebnis=", ergebnis);
            
let summe = f3(17, 23); // Übergibt Werte und speichert das Ergebnis
console.log("summe=", summe);
Wichtig zu verstehen

Wenn eine Funktion einen Wert mit return zurückgibt, muss dieser Wert in einer Variable gespeichert werden, wenn man ihn weiter verwenden möchte.

Funktionen mit mehreren Rückgabewerten (als Array):


function f4(a, b, c) {
    let summe = a + b + c;
    let mittelwert = summe / 3;
    return [summe, mittelwert]; // Mehrere Werte als Array zurückgeben
}
            
let ergebnisse = f4(2, 3, 4);
console.log("Summe:", ergebnisse[0], "Mittelwert:", ergebnisse[1]);

Funktionen mit optionalen Parametern und Standardwerten:


function f5(a, b, c = 0, d = 0) {
    // c und d sind optional und werden mit 0 initialisiert, wenn nicht angegeben
    let summe = a + b + c + d;
    let mittelwert = summe / 4;
    return [summe, mittelwert];
}
            
let e3 = f5(2, 3); // c und d werden mit 0 initialisiert
console.log("e3=", e3);

Funktionen mit Rest-Parameter für variable Anzahl von Argumenten:


function f7(...zahlen) {
    // zahlen ist ein Array mit allen übergebenen Argumenten
    let summe = 0;
    for(let i = 0; i < zahlen.length; i++) {
        summe += zahlen[i];
    }
    let mittelwert = zahlen.length > 0 ? summe / zahlen.length : 0;
    return [summe, mittelwert];
}
            
let e7 = f7(); // Kein Parameter
let e8 = f7(1, 2, 3, 4, 5, 6, 7, 8); // Mehrere Parameter

Arrow Functions

Arrow Functions (Pfeilfunktionen) sind eine kürzere Schreibweise für Funktionen, die in neueren JavaScript-Versionen verfügbar ist:


// Traditionelle Funktion
function add(a, b) {
    return a + b;
}
            
// Als Arrow Function (Pfeilfunktion)
const add2 = (a, b) => a + b;  // Kurzform ohne geschweifte Klammern gibt automatisch zurück
            
// Arrow Function mit Codeblock
const calc = (a, b) => {
    const result = a + b;
    return result;  // Bei geschweiften Klammern ist return erforderlich
};
            
// Arrow Function ohne Parameter
const sayHello = () => console.log("Hallo Welt!");
Hinweis

Arrow Functions haben kein eigenes this, sondern übernehmen das this aus dem umgebenden Kontext. Das macht sie besonders nützlich für Event-Handler und Callbacks, wo in traditionellen Funktionen oft Probleme mit this auftreten.

Bei einzeiligen Arrow Functions ohne geschweifte Klammern ist das return implizit - der Wert wird automatisch zurückgegeben.

Objekte

Objekt erstellen

Objekte sind Sammlungen von Eigenschaften (Schlüssel-Wert-Paare):


// Leeres Objekt erstellen
let o = {};

// Eigenschaften zuweisen
o["VN"] = "Uwe";
o["NN"] = "Mutz";
console.log(o);

// Objekt mit initialisierten Eigenschaften
let o2 = {
    VN: "Silvia",
    NN: "Mutz"
};
console.log(o2);

Zugriff auf Eigenschaften

Auf Objekteigenschaften kann auf zwei Arten zugegriffen werden:


// Bracket-Notation
    console.log(o2["VN"]); // Ausgabe: Silvia
                        
// Dot-Notation
    console.log(o2.VN); // Ausgabe: Silvia
                        
// Dynamischer Zugriff mit Variablen
    let x = "VN";
    console.log(o2[x]); // Ausgabe: Silvia
    console.log(o2.x);  // Ausgabe: undefined (es gibt keine Eigenschaft 'x')

Durch Objekte iterieren:



for(let eigenschaft in o2) {
    console.log(eigenschaft + ":", o2[eigenschaft]);
}

DOM-Manipulation

Das Document Object Model (DOM) ist eine Programmierschnittstelle für HTML- und XML-Dokumente. Es stellt die Struktur eines Dokuments als Baumstruktur dar, in der jeder Knoten ein Objekt ist, das einen Teil des Dokuments repräsentiert.

DOM-Selektoren

Elemente im DOM können auf verschiedene Arten ausgewählt werden:


// Ein einzelnes Element auswählen
let img = document.querySelector("img");
                        
// Mehrere Elemente auswählen
let paragraphen = document.querySelectorAll("p");
                        
// Zugriff auf das erste Paragraf-Element
let ersteParagraf = document.querySelector("p");
                        
// Zugriff auf den zweiten Paragraf
let zweiteParagraf = document.querySelectorAll("p")[1];
                        
// Elemente über ID auswählen
let button = document.querySelector("#btn0");

DOM-Elemente bearbeiten

Eigenschaften von DOM-Elementen können direkt geändert werden:


// Bild-Quelle ändern
document.querySelector("img").src = "bilder/bild2.jpg";
                        
// Alternativen Text und Titel setzen
document.querySelector("img").alt = "Das ist der alternative Text";
document.querySelector("img").title = "Ein Löwe...";
                        
// HTML-Inhalt ändern
document.querySelector("p").innerHTML = "Ein <strong>kleiner</strong> Test";
                        
// CSS-Klassen verwalten
console.log("Klassenliste:", document.querySelectorAll("p")[1].classList);
                        
// Klasse umschalten (hinzufügen/entfernen)
document.querySelectorAll("p")[1].classList.toggle("a");

Event-Handling

Events ermöglichen die Reaktion auf Benutzeraktionen:

Inline Event-Handler


<button type="button" id="btn0" onclick="document.querySelector('img').src = 'bilder/bild2.jpg';">
    wechsle das Bild
</button>

addEventListener-Methode


document.addEventListener("DOMContentLoaded", () => {
    const btn0 = document.querySelector("#btn0");
    
    btn0.addEventListener("click", () => {
        document.querySelector('img').src = 'bilder/bild2.jpg';
    });
});

Das DOMContentLoaded-Event:



document.addEventListener("DOMContentLoaded", function() {
    console.log("DOMContentLoaded ist aufgetreten");
    // Jetzt ist der DOM vollständig geladen und kann manipuliert werden
});
Hinweis

Das DOMContentLoaded-Event wird ausgelöst, wenn das HTML-Dokument vollständig geladen und geparst wurde. Es wartet nicht auf das Laden von Stylesheets, Bildern und Frames.

Verschiedene Event-Typen:


const btn0 = document.querySelector("#btn0");
const img0 = document.querySelector("img");
                        
// Click-Event
btn0.addEventListener("click", () => {
    img0.src = 'bilder/bild2.jpg';
});
                        
// Doppelklick-Event
btn0.addEventListener("dblclick", () => {
    img0.src = 'bilder/bild3.jpg';
});
                        
// Maus über Element
img0.addEventListener("mouseover", () => {
    img0.src = "bilder/bild4.jpg";
});
                        
// Maus verlässt Element
img0.addEventListener("mouseout", () => {
    img0.src = "bilder/bild1.jpg";
});

Formular-Events


document.addEventListener("DOMContentLoaded", () => {
    const frm = document.querySelector("form");
    frm.addEventListener("submit", (ev) => {
        ev.preventDefault(); // Verhindert das standardmäßige Absenden des Formulars
        
        // Formularvalidierung
        const pwd0 = document.querySelector("[name='P0']").value;
        if(pwd0.length >= 8) {
            // Passwortlänge ist ok
            const pwd1 = document.querySelector("[name='P1']").value;
            if(pwd0 == pwd1) {
                // Passwörter stimmen überein
                frm.submit(); // Formular absenden
            } else {
                document.querySelector("#errors").innerHTML = "Leider stimmen die Passwörter nicht überein";
            }
        } else {
            document.querySelector("#errors").innerHTML = "Leider ist das gewählte Passwokurz";
        }
    });
});

Zeitgesteuerte Funktionen

setTimeout

setTimeout führt Code einmalig nach einer bestimmten Verzögerung aus:


let gbl_to; // Globale Variable für das Timeout
                        
document.addEventListener("DOMContentLoaded", () => {
    // Führt die Funktion entferneButton nach 3 Sekunden aus
    gbl_to = setTimeout(entferneButton, 3000);
                            
    const btn0 = document.querySelector("#btn0");
    btn0.addEventListener("click", () => {
        clearTimeout(gbl_to); // Timeout löschen
        console.log("Das Timeout wurde gelöscht");
    });
});
                        
function entferneButton() {
    document.querySelector("#btn0").remove();
    console.log("Das Timeout wurde durchgeführt");
}

setInterval

setInterval führt Code wiederholt in regelmäßigen Abständen aus:


let gbl_itv; // Globale Variable für das Intervall
                        
document.addEventListener("DOMContentLoaded", () => {
    const btnPLAY = document.querySelector("#btnPlay");
    const btnSTOP = document.querySelector("#btnStop");
                            
    btnPLAY.addEventListener("click", () => {
        // Intervall starten, das alle 2 Sekunden die Funktion blaettern aufruft
        clearInterval(gbl_itv);
        gbl_itv = setInterval(() => { blaettern(1); }, 2000);
    });
                            
    btnSTOP.addEventListener("click", () => {
        clearInterval(gbl_itv);
    });
});

Praxisbeispiel: Bildergalerie

Dieses Beispiel zeigt, wie man eine einfache Bildergalerie mit JavaScript erstellt:

HTML-Struktur


<img src="bilder/galerie/bild0.jpg" alt=".." id="pic">
<div id="control">
    <button type="button" id="btnBack">‹</button>
    <button type="button" id="btnForward">›</button>
    <button type="button" id="btnPlay">Play</button>
    <button type="button" id="btnStop">Stop</button>
</div>

CSS-Styling


img {
    width: 20em;
    aspect-ratio: 16 / 9;
    object-fit: cover;
    object-position: center;
    display: block;
    margin: 1em auto;                     
    border: 2px solid grey;
    padding: 0.5em;
    border-radius: 0.2em;
}
#control {
    text-align: center;
}

JavaScript-Funktionalität



let bilder = [
    "bilder/galerie/bild0.jpg",
    "bilder/galerie/bild1.jpg",
    "bilder/galerie/bild2.jpg",
    "bilder/galerie/bild3.jpg",
    "bilder/galerie/bild4.jpg"
];
let bildzaehler = 0; // Index des aktuellen Bildes
let gbl_itv; // Variable für das Intervall
let gbl_itvrunning = false;
                        
document.addEventListener("DOMContentLoaded", () => {
    const btnFWD = document.querySelector("#btnForward");
    const btnBCK = document.querySelector("#btnBack");
    const btnPLAY = document.querySelector("#btnPlay");
    const btnSTOP = document.querySelector("#btnStop");
                            
    btnFWD.addEventListener("click", () => {
        blaettern(1);
    });
                            
    btnBCK.addEventListener("click", () => {
        blaettern(-1);
    });
                            
    btnPLAY.addEventListener("click", () => {
        starteIntervall();
    });
                            
    btnSTOP.addEventListener("click", () => {
        stoppeIntervall();
    });
});
                        
function blaettern(richtung) {
    clearInterval(gbl_itv);
                            
    bildzaehler += richtung;
    switch(true) {
        case bildzaehler == bilder.length:
            bildzaehler = 0;
            break;
        case bildzaehler == -1:
            bildzaehler = bilder.length - 1;
            break;
    }
    document.querySelector("#pic").src = bilder[bildzaehler];
    
    if(gbl_itvrunning) {
        starteIntervall();
    }
}
                        
function starteIntervall() {
    clearInterval(gbl_itv);
    gbl_itv = setInterval(() => { blaettern(1); }, 2000);
    gbl_itvrunning = true;
}
                        
function stoppeIntervall() {
    clearInterval(gbl_itv);
    gbl_itvrunning = false;
}

Zusätzliche Übungen zur Bildergalerie

Hier sind einige Erweiterungsideen für die Bildergalerie, die du selbständig umsetzen kannst:

Hinweis

Die folgenden Übungen bauen auf dem Basisbeispiel der Bildergalerie auf. Versuche, die Aufgaben selbst zu lösen, bevor du die Lösungen anschaust.

Übung 1: Bilder aus dem HTML-Code einlesen

Statt die Bildpfade im JavaScript-Array hart zu codieren, sollen die Bilder aus dem HTML-Code eingelesen werden.

Aufgabe: Implementiere eine Bildergalerie, die vorhandene <img>-Tags aus dem HTML-DOM ausliest, in ein Array speichert und anschließend für die Galerie verwendet.

HTML-Struktur



<div id="galerie">
    <img src="bilder/galerie/bild0.jpg" alt="..">
    <img src="bilder/galerie/bild1.jpg" alt="..">
    <img src="bilder/galerie/bild2.jpg" alt="..">
    <img src="bilder/galerie/bild3.jpg" alt="..">
    <img src="bilder/galerie/bild4.jpg" alt="..">
    <div id="control">
        <button type="button" id="btnBack">‹</button>
        <button type="button" id="btnForward">›</button>
        <button type="button" id="btnPlay">Play</button>
        <button type="button" id="btnStop">Stop</button>
    </div>
</div>

JavaScript-Lösung



let bilder = [];
                        let bildzaehler = 0; // Index des aktuellen Bildes
                        let gbl_itv; // Variable für das Intervall
                        let gbl_itvrunning = false;
                        
                        document.addEventListener("DOMContentLoaded", () => {
                            // Bilder einlesen und aus dem DOM entfernen
                            const htmlbilder = document.querySelectorAll("#galerie img");
                            for(let i = 0; i < htmlbilder.length; i++) {
                                bilder.push(htmlbilder[i].src);
                                htmlbilder[i].remove();
                            }
                            
                            // Neues Bild-Element für die Anzeige erstellen
                            const galerie = document.querySelector("#galerie");
                            galerie.innerHTML = '' + galerie.innerHTML;
                            
                            // Event-Handler für Buttons
                            const btnFWD = document.querySelector("#btnForward");
                            const btnBCK = document.querySelector("#btnBack");
                            const btnPLAY = document.querySelector("#btnPlay");
                            const btnSTOP = document.querySelector("#btnStop");
                            
                            btnFWD.addEventListener("click", () => {
                                blaettern(1);
                            });
                            
                            btnBCK.addEventListener("click", () => {
                                blaettern(-1);
                            });
                            
                            btnPLAY.addEventListener("click", () => {
                                starteIntervall();
                            });
                            
                            btnSTOP.addEventListener("click", () => {
                                stoppeIntervall();
                            });
                        });
                        
                        function blaettern(richtung) {
                            clearInterval(gbl_itv);
                            
                            bildzaehler += richtung;
                            switch(true) {
                                case bildzaehler == bilder.length:
                                    bildzaehler = 0;
                                    break;
                                case bildzaehler == -1:
                                    bildzaehler = bilder.length - 1;
                                    break;
                            }
                            document.querySelector("#pic").src = bilder[bildzaehler];
                            
                            if(gbl_itvrunning) {
                                starteIntervall();
                            }
                        }
                        
                        function starteIntervall() {
                            clearInterval(gbl_itv);
                            gbl_itv = setInterval(() => { blaettern(1); }, 2000);
                            gbl_itvrunning = true;
                        }
                        
                        function stoppeIntervall() {
                            clearInterval(gbl_itv);
                            gbl_itvrunning = false;
                        }

Übung 2: Galerie dynamisch generieren

Erstelle eine Bildergalerie, bei der der gesamte HTML-Code für die Galerie dynamisch mit JavaScript erzeugt wird.

Aufgabe: Implementiere eine Bildergalerie, deren HTML-Struktur (Bild und Steuerelemente) vollständig durch JavaScript generiert wird.

HTML-Struktur (minimal)



<!doctype html>
                        <html lang="de">
                            <head>
                                <title>Bildergalerie</title>
                                <meta charset="utf-8">
                                <!-- CSS und JavaScript hier -->
                            </head>
                            <body>
                                <!-- Leerer Body, der Inhalt wird durch JS generiert -->
                            </body>
                        </html>

JavaScript-Lösung



let bilder = [
                            "bilder/galerie/bild0.jpg",
                            "bilder/galerie/bild1.jpg",
                            "bilder/galerie/bild2.jpg",
                            "bilder/galerie/bild3.jpg",
                            "bilder/galerie/bild4.jpg"
                        ];
                        let bildzaehler = 0; // Index des aktuellen Bildes
                        let gbl_itv; // Variable für das Intervall
                        let gbl_itvrunning = false;
                        
                        document.addEventListener("DOMContentLoaded", () => {
                            // HTML-Code für die Galerie generieren
                            const body = document.querySelector("body");
                            body.innerHTML += '
..
'; // Event-Handler für Buttons const btnFWD = document.querySelector("#galerie #btnForward"); const btnBCK = document.querySelector("#galerie #btnBack"); const btnPLAY = document.querySelector("#galerie #btnPlay"); const btnSTOP = document.querySelector("#galerie #btnStop"); btnFWD.addEventListener("click", () => { blaettern(1); }); btnBCK.addEventListener("click", () => { blaettern(-1); }); btnPLAY.addEventListener("click", () => { starteIntervall(); }); btnSTOP.addEventListener("click", () => { stoppeIntervall(); }); }); function blaettern(richtung) { clearInterval(gbl_itv); bildzaehler += richtung; switch(true) { case bildzaehler == bilder.length: bildzaehler = 0; break; case bildzaehler == -1: bildzaehler = bilder.length - 1; break; } document.querySelector("#galerie #pic").src = bilder[bildzaehler]; if(gbl_itvrunning) { starteIntervall(); } } function starteIntervall() { clearInterval(gbl_itv); gbl_itv = setInterval(() => { blaettern(1); }, 2000); gbl_itvrunning = true; } function stoppeIntervall() { clearInterval(gbl_itv); gbl_itvrunning = false; }

Übung 3: Übergangseffekte

Erweitere die Bildergalerie um einen Fade-Effekt beim Bildwechsel.

Aufgabe: Implementiere eine Bildergalerie, bei der der Bildwechsel durch einen sanften Überblendeffekt realisiert wird.

HTML-Struktur



<div id="galerie">
                            <div id="pics">
                                <img src="bilder/galerie/bild0.jpg" alt="..">
                                <img src="bilder/galerie/bild1.jpg" alt="..">
                                <img src="bilder/galerie/bild2.jpg" alt="..">
                                <img src="bilder/galerie/bild3.jpg" alt="..">
                                <img src="bilder/galerie/bild4.jpg" alt="..">
                            </div>
                            <div id="control">
                                <button type="button" id="btnBack">‹</button>
                                <button type="button" id="btnForward">›</button>
                                <button type="button" id="btnPlay">Play</button>
                                <button type="button" id="btnStop">Stop</button>
                            </div>
                        </div>

CSS-Styling



img {
                            object-fit: cover;
                            object-position: center;
                            display: block;
                            
                            position: absolute;
                            left: 0px;
                            top: 0px;
                            width: 100%;
                            height: 100%;
                            
                            opacity: 100;
                            transition: opacity 1s;
                        }
                        #control {
                            text-align: center;
                        }
                        #pics {
                            position: relative;
                            width: 20em;
                            aspect-ratio: 16 / 9;
                            margin: 1em auto;
                            
                            border: 2px solid grey;
                            padding: 0.5em;
                            border-radius: 0.2em;
                        }
                        
                        .fade {
                            opacity: 0;
                        }

JavaScript-Lösung



let bilder = [];
                        let bildzaehler = 0; // Index des aktuellen Bildes
                        let gbl_itv; // Variable für das Intervall
                        let gbl_itvrunning = false;
                        
                        document.addEventListener("DOMContentLoaded", () => {
                            // Bilder einlesen und z-index setzen
                            const htmlbilder = document.querySelectorAll("#galerie img");
                            for(let i = 0; i < htmlbilder.length; i++) {
                                bilder.push(htmlbilder[i].src);
                                htmlbilder[i].style = "z-index:" + (-i);
                            }
                            
                            // Event-Handler für Buttons
                            const btnFWD = document.querySelector("#btnForward");
                            const btnBCK = document.querySelector("#btnBack");
                            const btnPLAY = document.querySelector("#btnPlay");
                            const btnSTOP = document.querySelector("#btnStop");
                            
                            btnFWD.addEventListener("click", () => {
                                blaettern(1);
                            });
                            
                            btnBCK.addEventListener("click", () => {
                                blaettern(-1);
                            });
                            
                            btnPLAY.addEventListener("click", () => {
                                starteIntervall();
                            });
                            
                            btnSTOP.addEventListener("click", () => {
                                stoppeIntervall();
                            });
                        });
                        
                        function blaettern(richtung) {
                            clearInterval(gbl_itv);
                            if(richtung == -1) {
                                // zurück ohne Animation
                                const pics = document.querySelectorAll("#pics img");
                                for(let i = 0; i < pics.length; i++) {
                                    let z = pics[i].style["z-index"];
                                    if(z == -pics.length + 1) {
                                        z = 1;
                                    }
                                    pics[i].style["z-index"] = z - 1;
                                }
                                setzeBildzaehler(richtung);
                            }
                            else {
                                blendeAus();
                                gbl_to = setTimeout(() => { reiheBilder(richtung); }, 1000);
                            }
                        }
                        
                        function blendeAus() {
                            const pic = document.querySelectorAll("#pics img")[bildzaehler];
                            pic.classList.add("fade");
                        }
                        
                        function reiheBilder(richtung) {
                            const pics = document.querySelectorAll("#pics img");
                            pics[bildzaehler].style["z-index"] = -pics.length;
                            for(let i = 0; i < pics.length; i++) {
                                let z = pics[i].style["z-index"];
                                pics[i].style["z-index"] = parseInt(z) + 1;
                            }
                            pics[bildzaehler].classList.remove("fade");
                            setzeBildzaehler(richtung);
                            if(gbl_itvrunning) {
                                starteIntervall();
                            }
                        }
                        
                        function setzeBildzaehler(richtung) {
                            bildzaehler += richtung;
                            switch(true) {
                                case bildzaehler == bilder.length:
                                    bildzaehler = 0;
                                    break;
                                case bildzaehler == -1:
                                    bildzaehler = bilder.length - 1;
                                    break;
                            }
                        }
                        
                        function starteIntervall() {
                            clearInterval(gbl_itv);
                            gbl_itv = setInterval(() => { blaettern(1); }, 3000);
                            gbl_itvrunning = true;
                        }
                        
                        function stoppeIntervall() {
                            clearInterval(gbl_itv);
                            gbl_itvrunning = false;
                        }

Best Practices

  • Verwendung von let und const: Verwende let für veränderliche Variablen und const für Konstanten anstelle von var.
  • Event-Delegation: Verwende Event-Delegation, um Events für mehrere Elemente effizient zu behandeln.
  • Vermeidung von globalen Variablen: Beschränke die Verwendung globaler Variablen und nutze stattdessen lokale Variablen innerhalb von Funktionen.
  • Kommentare und Dokumentation: Dokumentiere deinen Code mit sinnvollen Kommentaren.
  • Funktionsorientierte Programmierung: Teile komplexe Aufgaben in kleinere, wiederverwendbare Funktionen auf.
  • Trennung von Logik und Darstellung: Halte JavaScript-Code, HTML und CSS getrennt.
  • Fehlerbehandlung: Implementiere eine angemessene Fehlerbehandlung mit try/catch-Blöcken.

Zusammenfassung

Diese Lernunterlage deckt die Grundlagen von JavaScript ab, mit besonderem Fokus auf:

  • JavaScript-Syntax und Datentypen
  • Variablen und Ausgabemethoden
  • Bedingungen und Schleifen
  • Arrays und Objekte
  • Funktionen und Parameter
  • DOM-Manipulation und Event-Handling
  • Zeitgesteuerte Funktionen
  • Praxisbeispiel einer Bildergalerie

Durch die Kombination von theoretischen Konzepten und praktischen Beispielen sollte ein umfassendes Verständnis der JavaScript-Grundlagen erreicht werden.

EN