You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Web-Dev-For-Beginners/translations/de/7-bank-project/1-template-route
localizeflow[bot] da161c96d3
chore(i18n): sync translations with latest source changes (chunk 1/1, 464 changes)
7 months ago
..
README.md chore(i18n): sync translations with latest source changes (chunk 1/1, 464 changes) 7 months ago
assignment.md chore(i18n): sync translations with latest source changes (chunk 1/1, 464 changes) 7 months ago

README.md

Erstellen einer Banking-App Teil 1: HTML-Vorlagen und Routen in einer Webanwendung

journey
    title Ihre Entwicklung Ihrer Banking-App
    section SPA-Grundlagen
      Verstehen von Single-Page-Apps: 3: Student
      Lernvorlagenkonzepte: 4: Student
      Beherrsche DOM-Manipulation: 4: Student
    section Routing-Systeme
      Implementieren client-seitiges Routing: 4: Student
      Browser-Verlauf verwalten: 5: Student
      Navigationssysteme erstellen: 5: Student
    section Professionelle Muster
      Modulare Architektur aufbauen: 5: Student
      Beste Praktiken anwenden: 5: Student
      Benutzererfahrungen erstellen: 5: Student

Als der Apollo-11-Navigationscomputer 1969 zum Mond steuerte, musste er zwischen verschiedenen Programmen wechseln, ohne das gesamte System neu zu starten. Moderne Webanwendungen funktionieren ähnlich sie ändern, was du siehst, ohne alles neu zu laden. Dies schafft die flüssige, reaktionsschnelle Erfahrung, die Nutzer heute erwarten.

Im Gegensatz zu traditionellen Websites, die ganze Seiten bei jeder Interaktion neu laden, aktualisieren moderne Web-Apps nur die Teile, die sich ändern müssen. Dieser Ansatz, ähnlich wie die Missionskontrolle zwischen verschiedenen Anzeigen wechselt und gleichzeitig die Kommunikation aufrechterhält, schafft die flüssige Benutzererfahrung, die wir erwarten.

Das macht den Unterschied so dramatisch:

Traditionelle Multi-Page-Apps Moderne Single-Page-Apps
Navigation Volles Neuladen der Seite bei jedem Bildschirm
Leistung Langsamer durch vollständige HTML-Downloads
Benutzererfahrung Ruckartige Seitenwechsel
Datenaustausch Schwieriger zwischen Seiten
Entwicklung Mehrere HTML-Dateien zur Pflege

Evolution verstehen:

  • Traditionelle Apps benötigen Serveranfragen bei jeder Navigation
  • Moderne SPAs laden einmal und aktualisieren Inhalte dynamisch mit JavaScript
  • Nutzer erwarten jetzt sofortige, nahtlose Interaktionen
  • Leistungsverbesserungen umfassen geringeren Bandbreitenbedarf und schnellere Reaktionen

In dieser Lektion bauen wir eine Banking-App mit mehreren Bildschirmen, die nahtlos zusammenfließen. So wie Wissenschaftler modulare Instrumente verwenden, die für verschiedene Experimente neu konfiguriert werden können, verwenden wir HTML-Vorlagen als wiederverwendbare Komponenten, die bei Bedarf angezeigt werden.

Du arbeitest mit HTML-Vorlagen (wiederverwendbare Blaupausen für verschiedene Bildschirme), JavaScript-Routing (das System, das zwischen Bildschirmen wechselt) und der History-API des Browsers (die die Zurück-Schaltfläche wie erwartet funktionieren lässt). Das sind die grundlegenden Techniken, die auch Frameworks wie React, Vue und Angular verwenden.

Am Ende hast du eine funktionierende Banking-App, die professionelle Single-Page-Application-Prinzipien demonstriert.

mindmap
  root((Single-Page-Anwendungen))
    Architecture
      Template System
      Client-seitiges Routing
      Zustandsverwaltung
      Ereignisbehandlung
    Templates
      Wiederverwendbare Komponenten
      Dynamische Inhalte
      DOM-Manipulation
      Inhaltswechsel
    Routing
      URL-Verwaltung
      History API
      Navigationslogik
      Browser-Integration
    User Experience
      Schnelle Navigation
      Sanfte Übergänge
      Konsistenter Zustand
      Moderne Interaktionen
    Performance
      Reduzierte Serveranfragen
      Schnellere Seitenübergänge
      Effiziente Ressourcennutzung
      Bessere Reaktionsfähigkeit

Quiz vor der Vorlesung

Quiz vor der Vorlesung

Was du brauchst

Wir benötigen einen lokalen Webserver, um unsere Banking-App zu testen keine Sorge, das ist einfacher als es klingt! Falls du noch keinen hast, installiere einfach Node.js und führe npx lite-server aus deinem Projektordner aus. Dieser praktische Befehl startet einen lokalen Server und öffnet deine App automatisch im Browser.

Vorbereitung

Erstelle auf deinem Computer einen Ordner namens bank mit einer Datei namens index.html darin. Wir starten mit diesem HTML-Boilerplate:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Bank App</title>
  </head>
  <body>
    <!-- This is where you'll work -->
  </body>
</html>

Das bietet dir dieses Boilerplate:

  • Stellt die HTML5-Dokumentstruktur mit korrekter DOCTYPE-Deklaration her
  • Konfiguriert die Zeichencodierung auf UTF-8 für internationale Textunterstützung
  • Ermöglicht responsives Design mit dem Viewport-Meta-Tag für mobile Kompatibilität
  • Setzt einen aussagekräftigen Titel, der im Browser-Tab erscheint
  • Erstellt eine saubere Body-Sektion, in der wir unsere Anwendung aufbauen

📁 Projektstruktur-Vorschau

Am Ende dieser Lektion enthält dein Projekt:

bank/
├── index.html      <!-- Main HTML with templates -->
├── app.js          <!-- Routing and navigation logic -->
└── style.css       <!-- (Optional for future lessons) -->

Dateiverantwortlichkeiten:

  • index.html: Enthält alle Vorlagen und stellt die App-Struktur bereit
  • app.js: Verwaltet Routing, Navigation und Vorlagenverwaltung
  • Vorlagen: Definieren die Benutzeroberfläche für Login, Dashboard und weitere Bildschirme

HTML-Vorlagen

Vorlagen lösen ein grundlegendes Problem in der Webentwicklung. Als Gutenberg in den 1440er Jahren den Buchdruck mit beweglichen Lettern erfand, erkannte er, dass er anstelle ganzer Seiten wiederverwendbare Letternblöcke erstellen und nach Bedarf anordnen konnte. HTML-Vorlagen funktionieren nach demselben Prinzip anstelle separater HTML-Dateien für jede Seite definierst du wiederverwendbare Strukturen, die bei Bedarf angezeigt werden.

flowchart TD
    A["📋 Vorlagen-Definition"] --> B["💬 Versteckt im DOM"]
    B --> C["🔍 JavaScript findet Vorlage"]
    C --> D["📋 Vorlage-Inhalt klonen"]
    D --> E["🔗 An sichtbaren DOM anhängen"]
    E --> F["👁️ Benutzer sieht Inhalt"]
    
    G["Login-Vorlage"] --> A
    H["Dashboard-Vorlage"] --> A
    I["Zukünftige Vorlagen"] --> A
    
    style A fill:#e3f2fd
    style D fill:#e8f5e8
    style F fill:#fff3e0
    style B fill:#f3e5f5

Betrachte Vorlagen als Blaupausen für verschiedene Teile deiner App. So wie ein Architekt eine Blaupause erstellt und diese mehrmals nutzt, anstatt identische Räume neu zu zeichnen, erstellen wir Vorlagen einmal und instanziieren sie bei Bedarf. Der Browser hält diese Vorlagen verborgen, bis JavaScript sie aktiviert.

Wenn du mehrere Bildschirme für eine Webseite erstellen möchtest, wäre eine Möglichkeit, für jeden Bildschirm eine HTML-Datei anzulegen. Diese Lösung hat jedoch einige Nachteile:

  • Du musst das gesamte HTML neu laden, wenn du den Bildschirm wechselst, was langsam sein kann.
  • Es ist schwer, Daten zwischen den verschiedenen Bildschirmen zu teilen.

Eine andere Möglichkeit ist, nur eine HTML-Datei zu haben und mehrere HTML-Vorlagen mit dem <template>-Element zu definieren. Eine Vorlage ist ein wiederverwendbarer HTML-Block, der vom Browser nicht angezeigt wird und zur Laufzeit mit JavaScript instanziert werden muss.

Lass uns loslegen

Wir erstellen eine Banking-App mit zwei Hauptbildschirmen: einer Login-Seite und einem Dashboard. Fügen wir zuerst ein Platzhalter-Element zum HTML-Body hinzu hier erscheinen später all unsere verschiedenen Bildschirme:

<div id="app">Loading...</div>

Verständnis dieses Platzhalters:

  • Erstellt einen Container mit der ID „app“, in dem alle Bildschirme angezeigt werden
  • Zeigt eine Ladeanzeige, bis JavaScript den ersten Bildschirm initialisiert
  • Bietet einen einzigen Mount-Punkt für unseren dynamischen Inhalt
  • Ermöglicht einfaches Ansteuern aus JavaScript mit document.getElementById()

💡 Profi-Tipp: Da der Inhalt dieses Elements ersetzt wird, kannst du eine Ladeanzeige oder Meldung einfügen, die während des Ladens der App angezeigt wird.

Als nächstes fügen wir unterhalb eine HTML-Vorlage für die Login-Seite hinzu. Zunächst enthält sie nur einen Titel und eine Sektion mit einem Link, den wir für die Navigation verwenden:

<template id="login">
  <h1>Bank App</h1>
  <section>
    <a href="/dashboard">Login</a>
  </section>
</template>

Aufschlüsselung dieser Login-Vorlage:

  • Definiert eine Vorlage mit der eindeutigen Kennung „login“ für das Ansteuern per JavaScript
  • Enthält eine Hauptüberschrift, die das Branding der App etabliert
  • Beinhaltet ein semantisches <section>-Element zur Gruppierung verwandter Inhalte
  • Bietet einen Navigationslink, der die Nutzer zum Dashboard führt

Dann fügen wir noch eine weitere HTML-Vorlage für die Dashboard-Seite hinzu. Diese Seite enthält unterschiedliche Abschnitte:

  • Eine Kopfzeile mit Titel und Logout-Link
  • Den aktuellen Kontostand
  • Eine Liste von Transaktionen in einer Tabelle
<template id="dashboard">
  <header>
    <h1>Bank App</h1>
    <a href="/login">Logout</a>
  </header>
  <section>
    Balance: 100$
  </section>
  <section>
    <h2>Transactions</h2>
    <table>
      <thead>
        <tr>
          <th>Date</th>
          <th>Object</th>
          <th>Amount</th>
        </tr>
      </thead>
      <tbody></tbody>
    </table>
  </section>
</template>

Verständnis der einzelnen Bestandteile des Dashboards:

  • Strukturiert die Seite mit einem semantischen <header>-Element mit Navigation
  • Zeigt den App-Titel konsistent auf allen Bildschirmen für Branding
  • Bietet einen Logout-Link, der zurück zur Login-Seite navigiert
  • Zeigt den aktuellen Kontostand in einem eigenen Abschnitt an
  • Organisiert Transaktionsdaten in einer korrekt strukturierten HTML-Tabelle
  • Definiert Tabellenüberschriften für Datum, Objekt und Betrag
  • Lässt den Tabellenkörper leer für spätere dynamische Befüllung

💡 Profi-Tipp: Möchtest du eine HTML-Vorlage ansehen, kannst du die <template>- und </template>-Zeilen auskommentieren, indem du sie mit <!-- --> umschließt.

🔄 Pädagogisches Check-in

Verständnis des Vorlagensystems: Bevor du mit JavaScript beginnst, solltest du sicherstellen:

  • Wie sich Vorlagen von normalen HTML-Elementen unterscheiden
  • Warum Vorlagen verborgen bleiben, bis JavaScript sie aktiviert
  • Die Bedeutung einer semantisch korrekten HTML-Struktur in Vorlagen
  • Wie Vorlagen wiederverwendbare UI-Komponenten ermöglichen

Schnelltest: Was passiert, wenn du die <template>-Tags um dein HTML entfernst?
Antwort: Der Inhalt wird sofort sichtbar und verliert seine Vorlagenfunktion.

Architekturvorteile: Vorlagen bieten:

  • Wiederverwendbarkeit: Eine Definition, mehrere Instanzen
  • Leistung: Kein überflüssiges HTML-Parsen
  • Wartbarkeit: Zentrale UI-Struktur
  • Flexibilität: Dynamischer Inhaltswechsel

Warum denkst du, verwenden wir id-Attribute für die Vorlagen? Könnten wir stattdessen Klassen nutzen?

Vorlagen mit JavaScript zum Leben erwecken

Jetzt müssen wir unsere Vorlagen funktionsfähig machen. So wie ein 3D-Drucker eine digitale Blaupause nimmt und ein physisches Objekt erstellt, nimmt JavaScript unsere versteckten Vorlagen und erzeugt sichtbare, interaktive Elemente, die Nutzer sehen und verwenden können.

Der Prozess folgt drei konsistenten Schritten, die die Grundlage moderner Webentwicklung bilden. Sobald du diesen Ablauf verstehst, wirst du ihn in vielen Frameworks und Bibliotheken wiedererkennen.

Wenn du deine aktuelle HTML-Datei im Browser öffnest, siehst du nur „Loading...“. Das liegt daran, dass wir noch JavaScript-Code hinzufügen müssen, der die HTML-Vorlagen instanziiert und anzeigt.

Eine Vorlage wird normalerweise in 3 Schritten instanziiert:

  1. Das Template-Element im DOM abrufen, z. B. mit document.getElementById.
  2. Das Template-Element klonen mit cloneNode.
  3. Das geklonte Element in den DOM einfügen, z. B. mit appendChild.
flowchart TD
    A[🔍 Schritt 1: Vorlage finden] --> B[📋 Schritt 2: Vorlage klonen]
    B --> C[🔗 Schritt 3: An DOM anhängen]
    
    A1["document.getElementById('login')"] --> A
    B1["template.content.cloneNode(true)"] --> B  
    C1["app.appendChild(view)"] --> C
    
    C --> D[👁️ Vorlage für Benutzer sichtbar]
    
    style A fill:#e1f5fe
    style B fill:#f3e5f5
    style C fill:#e8f5e8
    style D fill:#fff3e0

Visuelle Aufschlüsselung des Ablaufs:

  • Schritt 1 findet die verborgene Vorlage in der DOM-Struktur
  • Schritt 2 erstellt eine Arbeitskopie, die sicher modifiziert werden kann
  • Schritt 3 fügt die Kopie in den sichtbaren Seitenbereich ein
  • Ergebnis ist ein funktionaler Bildschirm, mit dem Nutzer interagieren können

Warum müssen wir die Vorlage klonen, bevor wir sie in den DOM einfügen? Was denkst du, passiert, wenn wir diesen Schritt überspringen?

Aufgabe

Erstelle eine neue Datei namens app.js in deinem Projektordner und binde diese Datei im <head>-Bereich deiner HTML-Datei ein:

<script src="app.js" defer></script>

Verständnis dieses Skriptimports:

  • Verknüpft die JavaScript-Datei mit unserem HTML-Dokument
  • Verwendet das defer-Attribut, um sicherzustellen, dass das Skript nach dem Parsen des HTML ausgeführt wird
  • Ermöglicht Zugriff auf alle DOM-Elemente, die vor Skriptausführung vollständig geladen sind
  • Folgt modernen Best Practices für Ladezeiten und Performance

Jetzt erstellen wir in app.js eine neue Funktion updateRoute:

function updateRoute(templateId) {
  const template = document.getElementById(templateId);
  const view = template.content.cloneNode(true);
  const app = document.getElementById('app');
  app.innerHTML = '';
  app.appendChild(view);
}

Schritt für Schritt passiert hier:

  • Findet das Template-Element anhand seiner eindeutigen ID
  • Erstellt eine tiefgehende Kopie des Vorlageninhalts mit cloneNode(true)
  • Findet den App-Container, in dem der Inhalt angezeigt wird
  • Leert den vorhandenen Inhalt des App-Containers
  • Fügt die geklonte Vorlage in den sichtbaren DOM-Bereich ein

Rufe diese Funktion nun mit einer der Vorlagen auf und sieh dir das Ergebnis an.

updateRoute('login');

Was dieser Funktionsaufruf bewirkt:

  • Aktiviert die Login-Vorlage, indem die ID übergeben wird
  • Demonstriert, wie man zwischen verschiedenen App-Bildschirmen programmatisch wechselt
  • Zeigt den Login-Bildschirm anstelle der Anzeige „Loading...“

Wozu dient dieser Code app.innerHTML = '';? Was passiert ohne ihn?

Routen erstellen

Routing bedeutet im Wesentlichen, URLs mit dem richtigen Inhalt zu verbinden. Stell dir vor, wie frühe Telefonistinnen mit einem Vermittlungspult Anrufe weiterleiteten sie nahmen eine eingehende Anfrage und leiteten sie an das richtige Ziel weiter. Web-Routing funktioniert ähnlich, es nimmt eine URL-Anfrage und entscheidet, welcher Inhalt angezeigt wird.

flowchart LR
    A["🌐 URL-Pfad<br/>/dashboard"] --> B["🗺️ Routen-Objekt<br/>Nachschlagen"]
    B --> C["🎯 Vorlagen-ID<br/>'dashboard'"]
    C --> D["📌 Vorlage finden<br/>getElementById"]
    D --> E["👁️ Bildschirm anzeigen<br/>Klonen & Anhängen"]
    
    F["📍 /login"] --> G["🎯 'login'"]
    H["📍 /unknown"] --> I["❌ Nicht gefunden"]
    I --> J["🔄 Weiterleitung zu /login"]
    
    style B fill:#e3f2fd
    style E fill:#e8f5e8
    style I fill:#ffebee
    style J fill:#fff3e0

Traditionell lief das so ab, dass Webserver für verschiedene URLs unterschiedliche HTML-Dateien lieferten. Da wir eine Single-Page-App bauen, müssen wir dieses Routing selbst mit JavaScript übernehmen. Dieser Ansatz gibt uns mehr Kontrolle über Nutzererfahrung und Performance.

flowchart LR
    A["🌐 URL-Pfad<br/>/dashboard"] --> B["🗺️ Routenobjekt<br/>Nachschlagen"]
    B --> C["🎯 Template-ID<br/>'dashboard'"]
    C --> D["📄 Vorlage finden<br/>getElementById"]
    D --> E["👁️ Bildschirm anzeigen<br/>Klone & Anhängen"]
    
    F["📍 /login"] --> G["🎯 'login'"]
    H["📍 /unbekannt"] --> I["❌ Nicht gefunden"]
    I --> J["🔄 Umleitung zu /login"]
    
    style B fill:#e3f2fd
    style E fill:#e8f5e8
    style I fill:#ffebee
    style J fill:#fff3e0

So funktioniert der Routing-Ablauf:

  • URL-Änderungen lösen eine Suche in unserer Routen-Konfiguration aus
  • Gültige Routen verknüpfen mit spezifischen Vorlagen-IDs zur Anzeige
  • Ungültige Routen lösen eine Fallback-Logik aus, um Fehlerzustände zu vermeiden
  • Vorlagenanzeige folgt dem dreistufigen Prozess, den wir zuvor gelernt haben

In einer Web-App nennen wir Routing die Absicht, URLs auf bestimmte Bildschirme abzubilden, die angezeigt werden sollen. Auf Webseiten mit mehreren HTML-Dateien passiert das automatisch, da die Dateipfade in der URL widergespiegelt werden. Beispielhaft mit diesen Dateien im Projektordner:

mywebsite/index.html
mywebsite/login.html
mywebsite/admin/index.html

Wenn du einen Webserver mit mywebsite als Root einrichtest, sieht die URL-Zuordnung so aus:

https://site.com            --> mywebsite/index.html
https://site.com/login.html --> mywebsite/login.html
https://site.com/admin/     --> mywebsite/admin/index.html

Da wir jedoch eine einzelne HTML-Datei mit allen Bildschirmen verwenden, hilft uns dieses Standardverhalten nicht weiter. Wir müssen die Zuordnung manuell erstellen und mit JavaScript den angezeigten Inhalt aktualisieren.

Aufgabe

Wir verwenden ein einfaches Objekt, um eine Zuordnung zwischen URL-Pfaden und unseren Vorlagen zu implementieren. Füge dieses Objekt am Anfang deiner app.js ein.

const routes = {
  '/login': { templateId: 'login' },
  '/dashboard': { templateId: 'dashboard' },
};

Verständnis der Routen-Konfiguration:

  • Definiert eine Zuordnung zwischen URL-Pfaden und Vorlagen-IDs
  • Verwendet Objektsyntax, bei der Schlüssel URL-Pfade und Werte Vorlageninformationen sind
  • Ermöglicht einfache Abfrage, welche Vorlage für eine URL angezeigt werden soll
  • Bietet eine skalierbare Struktur zum Hinzufügen weiterer Routen in der Zukunft Nun modifizieren wir die Funktion updateRoute ein wenig. Statt die templateId direkt als Argument zu übergeben, wollen wir sie zunächst aus der aktuellen URL auslesen und dann unsere Map verwenden, um den entsprechenden Template-ID-Wert zu erhalten. Wir können window.location.pathname verwenden, um nur den Pfadteil aus der URL zu bekommen.
function updateRoute() {
  const path = window.location.pathname;
  const route = routes[path];

  const template = document.getElementById(route.templateId);
  const view = template.content.cloneNode(true);
  const app = document.getElementById('app');
  app.innerHTML = '';
  app.appendChild(view);
}

Aufschlüsselung dessen, was hier passiert:

  • Extrahiert den aktuellen Pfad aus der URL des Browsers mit window.location.pathname
  • Sucht die entsprechende Routen-Konfiguration in unserem Routes-Objekt
  • Ruft ab die Template-ID aus der Routen-Konfiguration
  • Folgt dem gleichen Template-Render-Prozess wie zuvor
  • Erstellt ein dynamisches System, das auf URL-Änderungen reagiert

Hier haben wir die deklarierten Routen der entsprechenden Vorlage zugeordnet. Du kannst ausprobieren, dass es richtig funktioniert, indem du die URL manuell in deinem Browser änderst.

Was passiert, wenn du einen unbekannten Pfad in die URL eingibst? Wie könnten wir das lösen?

Navigation hinzufügen

Mit der Routensteuerung brauchen Benutzer eine Möglichkeit, durch die App zu navigieren. Traditionelle Webseiten laden beim Klicken auf Links ganze Seiten neu, aber wir wollen sowohl die URL als auch den Inhalt ändern, ohne die Seite neu zu laden. Das erzeugt ein flüssigeres Erlebnis, ähnlich wie Desktop-Anwendungen zwischen verschiedenen Ansichten wechseln.

Wir müssen zwei Dinge koordinieren: die URL im Browser aktualisieren, damit Benutzer Seiten mit Lesezeichen versehen und Links teilen können, und den passenden Inhalt anzeigen. Richtig umgesetzt, entsteht so die nahtlose Navigation, die moderne Anwendungen bieten.

sequenceDiagram
    participant User
    participant Browser
    participant App
    participant Template
    
    User->>Browser: Klickt auf "Login" Link
    Browser->>App: onclick Ereignis ausgelöst
    App->>App: preventDefault() & navigate('/dashboard')
    App->>Browser: history.pushState('/dashboard')
    Browser->>Browser: URL aktualisiert auf /dashboard
    App->>App: updateRoute() aufgerufen
    App->>Template: Dashboard-Vorlage finden & klonen
    Template->>App: Geklonten Inhalt zurückgeben
    App->>Browser: App-Inhalt durch Vorlage ersetzen
    Browser->>User: Dashboard-Bildschirm anzeigen
    
    Note over User,Template: Benutzer klickt auf den Zurück-Button des Browsers
    
    User->>Browser: Klickt Rückwärts-Button
    Browser->>Browser: Verlauf geht zurück zu /login
    Browser->>App: popstate Ereignis ausgelöst
    App->>App: updateRoute() wird automatisch aufgerufen
    App->>Template: Login-Vorlage finden & klonen
    Template->>App: Geklonten Inhalt zurückgeben
    App->>Browser: App-Inhalt durch Vorlage ersetzen
    Browser->>User: Login-Bildschirm anzeigen

🔄 Pädagogischer Check-in

Single-Page-Application-Architektur: Verifiziere dein Verständnis des Gesamtsystems:

  • Wie unterscheidet sich Client-seitiges Routing vom traditionellen serverseitigen Routing?
  • Warum ist die History-API für eine korrekte SPA-Navigation unverzichtbar?
  • Wie ermöglichen Templates dynamische Inhalte ohne Seiten-Neuladen?
  • Welche Rolle spielt Event-Handling beim Abfangen der Navigation?

Systemintegration: Deine SPA zeigt:

  • Template-Verwaltung: Wiederverwendbare UI-Komponenten mit dynamischem Inhalt
  • Client-seitiges Routing: URL-Verwaltung ohne Serveranfragen
  • Ereignisgesteuerte Architektur: Reaktionsfähige Navigation und Benutzerinteraktion
  • Browser-Integration: Korrekte Unterstützung von History- und Zurück/Vorwärts-Tasten
  • Performance-Optimierung: Schnelle Übergänge und verringerte Serverlast

Professionelle Muster: Du hast implementiert:

  • Modell-View-Trennung: Templates getrennt von der Anwendungslogik
  • Zustandsverwaltung: URL-Zustand synchronisiert mit angezeigten Inhalten
  • Progressive Enhancement: JavaScript erweitert grundlegende HTML-Funktionalität
  • Benutzererlebnis: Fließende, app-ähnliche Navigation ohne Seiten-Neuladen

<EFBFBD> Architektur-Insight: Komponenten des Navigationssystems

Was du baust:

  • 🔄 URL-Verwaltung: Aktualisiert die Adressleiste ohne Seiten-Neuladen
  • 📋 Template-System: Tauscht Inhalte dynamisch basierend auf der aktuellen Route
  • 📚 History-Integration: Erhält Funktionalität der Vor-/Zurück-Buttons im Browser
  • 🛡️ Fehlerbehandlung: Elegante Fallbacks bei ungültigen oder fehlenden Routen

Wie die Komponenten zusammenarbeiten:

  • Hört auf Navigationsereignisse (Klicks, History-Änderungen)
  • Aktualisiert die URL mit der History-API
  • Rendert das passende Template für die neue Route
  • Ermöglicht durchgängig ein nahtloses Benutzererlebnis

Der nächste Schritt für unsere App ist, die Möglichkeit hinzuzufügen, zwischen Seiten zu navigieren, ohne die URL manuell ändern zu müssen. Das bedeutet zwei Dinge:

  1. Aktualisierung der aktuellen URL
  2. Aktualisierung des angezeigten Templates basierend auf der neuen URL

Den zweiten Teil haben wir bereits mit der Funktion updateRoute abgedeckt, also müssen wir herausfinden, wie wir die aktuelle URL aktualisieren.

Wir müssen JavaScript verwenden und genauer gesagt history.pushState, mit dem man die URL ändern und einen neuen Eintrag im Browser-Verlauf erzeugen kann, ohne das HTML neu zu laden.

⚠️ Wichtiger Hinweis: Während das HTML-Ankerelement <a href> allein verwendet werden kann, um Hyperlinks zu verschiedenen URLs zu erzeugen, führt es standardmäßig zu einem Neu-Laden der Seite. Dieses Verhalten muss beim Handling des Routings mit eigenem JavaScript durch Aufruf von preventDefault() im Klick-Event verhindert werden.

Aufgabe

Erstellen wir eine neue Funktion, mit der wir in unserer App navigieren können:

function navigate(path) {
  window.history.pushState({}, path, path);
  updateRoute();
}

Was diese Navigationsfunktion macht:

  • Aktualisiert die URL des Browsers mit dem neuen Pfad per history.pushState
  • Fügt einen neuen Eintrag in den Browser-Verlauf hinzu, damit Vor-/Zurück-Schaltflächen funktionieren
  • Löst die Funktion updateRoute() aus, um das passende Template anzuzeigen
  • Ermöglicht das SPA-Erlebnis ohne Seiten-Neuladen

Diese Methode aktualisiert zuerst die aktuelle URL anhand des übergebenen Pfads, dann wird das Template aktualisiert. Die Eigenschaft window.location.origin liefert die URL-Root zurück, mit der wir aus einem Pfad eine vollständige URL rekonstruieren können.

Da wir jetzt diese Funktion haben, kümmern wir uns um das Problem, wenn ein Pfad keiner definierten Route entspricht. Wir modifizieren updateRoute und fügen eine Fallback-Route hinzu, falls kein Treffer gefunden wird.

function updateRoute() {
  const path = window.location.pathname;
  const route = routes[path];

  if (!route) {
    return navigate('/login');
  }

  const template = document.getElementById(route.templateId);
  const view = template.content.cloneNode(true);
  const app = document.getElementById('app');
  app.innerHTML = '';
  app.appendChild(view);
}

Wichtige Punkte, die man sich merken sollte:

  • Prüft, ob eine Route für den aktuellen Pfad existiert
  • Leitet um auf die Login-Seite, wenn eine ungültige Route aufgerufen wird
  • Bietet einen Fallback-Mechanismus, der kaputte Navigation verhindert
  • Sorgt dafür, dass Benutzer immer einen gültigen Bildschirm sehen, selbst bei falschen URLs

Wenn keine Route gefunden wird, leiten wir jetzt zur login-Seite weiter.

Nun erstellen wir eine Funktion, um die URL beim Klicken eines Links zu ermitteln und das normale Linkverhalten des Browsers zu verhindern:

function onLinkClick(event) {
  event.preventDefault();
  navigate(event.target.href);
}

Aufschlüsselung dieses Klick-Handlers:

  • Verhindert mit preventDefault() das Standardverhalten des Browsers bei Links
  • Liest aus die Ziel-URL aus dem geklickten Link-Element aus
  • Ruft auf unsere benutzerdefinierte Navigate-Funktion auf, statt die Seite neu zu laden
  • Ermöglicht das flüssige SPA-Erlebnis ohne Seiten-Neuladen
<a href="/dashboard" onclick="onLinkClick(event)">Login</a>
...
<a href="/login" onclick="onLinkClick(event)">Logout</a>

Was diese onclick-Zuweisung bewirkt:

  • Verbindet jeden Link mit unserem individuellen Navigationssystem
  • Übergibt das Klick-Event an unsere Funktion onLinkClick zur Verarbeitung
  • Ermöglicht eine flüssige Navigation ohne Seiten-Neuladen
  • Erhält die korrekte URL-Struktur, die Benutzer als Lesezeichen speichern oder teilen können

Das onclick-Attribut bindet das Klick-Ereignis an JavaScript-Code, hier den Aufruf von navigate().

Versuche auf diese Links zu klicken, du solltest nun zwischen den verschiedenen Screens deiner App navigieren können.

Die Methode history.pushState ist Teil des HTML5-Standards und in allen modernen Browsern implementiert. Wenn du eine Web-App für ältere Browser baust, gibt es einen Trick als Ersatz: Mit einem Hash (#) vor dem Pfad kannst du Routing bauen, das mit normalen Anker-Navigationen funktioniert und die Seite nicht neu lädt ursprünglich zur Erstellung interner Links auf einer Seite gedacht.

Die Vorwärts- und Zurück-Tasten zum Laufen bringen

Die Vorwärts- und Zurück-Schaltflächen sind fundamental für das Web-Browsing, so wie NASA Missions-Kontrolleure vorherige Systemzustände während Raumfahrtmissionen überprüfen können. Benutzer erwarten, dass diese Buttons funktionieren. Wenn nicht, bricht das das erwartete Browser-Erlebnis.

Unsere Single-Page-App braucht dazu eine zusätzliche Konfiguration. Der Browser verwaltet einen Verlaufs-Stack (den wir mit history.pushState füllen), aber wenn Nutzer durch diesen Verlauf navigieren, muss unsere App darauf reagieren und den angezeigten Inhalt anpassen.

sequenceDiagram
    participant User
    participant Browser
    participant App
    participant Template
    
    User->>Browser: Klickt "Anmelden" Link
    Browser->>App: onclick Ereignis ausgelöst
    App->>App: preventDefault() & navigate('/dashboard')
    App->>Browser: history.pushState('/dashboard')
    Browser->>Browser: URL aktualisiert auf /dashboard
    App->>App: updateRoute() aufgerufen
    App->>Template: Dashboard Vorlage finden & klonen
    Template->>App: Geklonten Inhalt zurückgeben
    App->>Browser: App-Inhalt mit Vorlage ersetzen
    Browser->>User: Dashboard Bildschirm anzeigen
    
    Note over User,Template: Benutzer klickt Browser-Zurück-Schaltfläche
    
    User->>Browser: Klickt Zurück-Schaltfläche
    Browser->>Browser: Verlauf geht zurück zu /login
    Browser->>App: popstate Ereignis ausgelöst
    App->>App: updateRoute() automatisch aufgerufen
    App->>Template: Login Vorlage finden & klonen
    Template->>App: Geklonten Inhalt zurückgeben
    App->>Browser: App-Inhalt mit Vorlage ersetzen
    Browser->>User: Login Bildschirm anzeigen

Wichtige Interaktionspunkte:

  • Benutzeraktionen lösen Navigation über Klicks oder Browser-Buttons aus
  • App fängt Link-Klicks ab, um Seiten-Neuladen zu verhindern
  • History-API verwaltet URL-Änderungen und den Browser-Verlaufs-Stack
  • Templates liefern die Inhaltsstruktur für jeden Screen
  • Event-Listener sorgen dafür, dass die App auf alle Navigationsarten reagiert

Der Aufruf von history.pushState erzeugt neue Einträge im Browser-Verlauf. Du kannst das überprüfen, indem du den Zurück-Button im Browser gedrückt hältst es wird so etwas angezeigt wie:

Screenshot des Navigationsverlaufs

Wenn du mehrmals auf den Zurück-Button klickst, siehst du, dass sich die aktuelle URL ändert und der Verlauf aktualisiert wird, aber immer das gleiche Template bleibt angezeigt.

Das liegt daran, dass die Anwendung nicht weiß, dass sie bei jeder Änderung des Verlaufs updateRoute() aufrufen muss. Wenn du in die history.pushState-Dokumentation schaust, siehst du, dass beim Zustandswechsel also Wechsel zu einer anderen URL das Event popstate ausgelöst wird. Dieses Event werden wir verwenden, um das Problem zu lösen.

Aufgabe

Um sicherzustellen, dass das angezeigte Template aktualisiert wird, wenn sich die Browser-Historie ändert, fügen wir eine neue Funktion hinzu, die updateRoute() aufruft. Das machen wir am Ende unserer app.js Datei:

window.onpopstate = () => updateRoute();
updateRoute();

Verständnis dieser History-Integration:

  • Hört auf popstate-Events, die ausgelöst werden, wenn Nutzer mit Browser-Buttons navigieren
  • Verwendet eine Arrow-Funktion für prägnante Event-Handler-Syntax
  • Ruft automatisch updateRoute() auf, wenn sich der History-Status ändert
  • Initialisiert die App, indem updateRoute() beim ersten Laden der Seite aufgerufen wird
  • Stellt sicher, dass immer das korrekte Template angezeigt wird, egal wie Nutzer navigieren

💡 Profi-Tipp: Hier haben wir eine Arrow-Funktion als popstate-Event-Handler verwendet, da sie kompakt ist. Eine normale Funktion würde genauso funktionieren.

Hier ein Auffrischungsvideo zu Arrow-Funktionen:

Arrow Functions

🎥 Klicke auf das Bild oben für ein Video zu Arrow-Funktionen.

Versuche jetzt, die Vorwärts- und Zurück-Buttons deines Browsers zu benutzen und prüfe, ob die angezeigte Route diesmal korrekt aktualisiert wird.

Was Du in den nächsten 5 Minuten tun kannst

  • Teste die Navigation deiner Banking-App mit den Browser-Vor-/Zurück-Buttons
  • Tippe manuell unterschiedliche URLs in die Adressleiste ein und teste das Routing
  • Öffne die DevTools deines Browsers und untersuche, wie Templates in den DOM geklont werden
  • Experimentiere mit console.log-Statements, um den Routing-Fluss zu verfolgen

🎯 Was Du in dieser Stunde erreichen kannst

  • Beende das Post-Lesson-Quiz und verstehe SPA-Architektur-Konzepte
  • Füge CSS-Styling hinzu, um die Templates der Banking-App professionell zu gestalten
  • Implementiere die 404-Fehlerseite mit entsprechender Fehlerbehandlung
  • Erstelle die Credits-Seite mit zusätzlicher Routing-Funktionalität
  • Füge Ladezustände und Übergänge beim Template-Wechsel hinzu

📅 Deine einwöchige SPA-Entwicklungsreise

  • Fertigstellung der kompletten Banking-App mit Formularen, Datenverwaltung und Persistenz
  • Erweiterte Routing-Features wie Route-Parameter und verschachtelte Routen hinzufügen
  • Implementierung von Navigations-Schutz und authentifizierungsbasiertem Routing
  • Erstellung wiederverwendbarer Template-Komponenten und einer Komponentenbibliothek
  • Hinzufügen von Animationen und Übergängen für ein flüssigeres Nutzererlebnis
  • Deployment deiner SPA auf einer Hosting-Plattform mit korrekter Routing-Konfiguration

🌟 Deine einmonatige Frontend-Architektur-Meisterschaft

  • Bau komplexer SPAs mit modernen Frameworks wie React, Vue oder Angular
  • Erlerne fortgeschrittene State-Management-Pattern und Bibliotheken
  • Meistere Build-Tools und Entwicklungs-Workflows für SPA-Entwicklung
  • Implementiere Progressive Web App Features und Offline-Funktionalität
  • Studiere Performance-Optimierungstechniken für großangelegte SPAs
  • Trage zu Open-Source SPA-Projekten bei und teile dein Wissen

🎯 Dein Single-Page-Application-Meisterungs-Zeitplan

timeline
    title SPA-Entwicklung & Lernen der modernen Webarchitektur
    
    section Grundlagen (20 Minuten)
        Templatesysteme: HTML-Template-Elemente
                         : DOM-Manipulation
                         : Inhalt kopieren
                         : Dynamisches Rendering
        
    section Routing-Grundlagen (30 Minuten)
        Client-seitige Navigation: URL-Verwaltung
                                 : History API
                                 : Routenabbildung
                                 : Ereignisbehandlung
        
    section Benutzererfahrung (40 Minuten)
        Navigation Details: Browserintegration
                            : Unterstützung des Zurück-Buttons
                            : Fehlerbehandlung
                            : Sanfte Übergänge
        
    section Architektur-Muster (50 Minuten)
        Professionelle SPAs: Komponenten-Systeme
                            : Zustandsverwaltung
                            : Leistungsoptimierung
                            : Fehlergrenzen
        
    section Fortgeschrittene Techniken (1 Woche)
        Framework-Integration: React Router
                              : Vue Router
                              : Angular Router
                              : Zustandsbibliotheken
        
    section Produktionsfähigkeiten (1 Monat)
        Unternehmensentwicklung: Build-Systeme
                                 : Teststrategien
                                 : Deployment-Pipelines
                                 : Leistungsüberwachung

🛠️ Deine SPA-Entwickler-Toolbox Zusammenfassung

Nach Abschluss dieser Lektion beherrschst du nun:

  • Template-Architektur: Wiederverwendbare HTML-Komponenten mit dynamischer Inhaltserstellung
  • Client-seitiges Routing: URL-Management und Navigation ohne Seiten-Neuladen
  • Browser-Integration: Verwendung der History-API und Unterstützung von Vor-/Zurück-Buttons
  • Ereignisgesteuerte Systeme: Navigationssteuerung und Verwaltung von Benutzerinteraktionen
  • DOM-Manipulation: Template-Klonen, Inhaltstausch und Elementverwaltung
  • Fehlerbehandlung: Elegante Fallbacks bei ungültigen Routen und fehlendem Inhalt
  • Performance-Muster: Effizientes Laden und Rendern von Inhalten

Anwendungen aus der Praxis: Deine SPA-Entwicklungsfähigkeiten sind direkt anwendbar auf:

  • Moderne Webanwendungen: Entwicklung mit React, Vue, Angular und anderen Frameworks
  • Progressive Web Apps: Offline-fähige Apps mit App-ähnlichem Erlebnis
  • Enterprise Dashboards: Komplexe Business-Applikationen mit mehreren Ansichten
  • E-Commerce-Plattformen: Produktkataloge, Warenkorb und Checkout-Flows
  • Content Management: Dynamische Erstellung und Bearbeitung von Inhalten
  • Mobile Entwicklung: Hybride Apps mit Webtechnologien

Erworbene professionelle Fähigkeiten: Du kannst nun:

  • Architektion von Single-Page-Anwendungen mit klarer Trennung der Verantwortlichkeiten
  • Implementierung von clientseitigen Routing-Systemen, die mit der Komplexität der Anwendung skalieren
  • Debugging komplexer Navigationsabläufe mit Browser-Entwicklertools
  • Optimierung der Anwendungsleistung durch effizientes Template-Management
  • Gestaltung von Benutzererlebnissen, die sich natív und responsiv anfühlen

Beherrschte Frontend-Entwicklungskonzepte:

  • Komponentenarchitektur: Wiederverwendbare UI-Muster und Templatesysteme
  • Zustandssynchronisation: URL-Zustandsverwaltung und Browserverlauf
  • Ereignisgesteuerte Programmierung: Nutzerinteraktionsverarbeitung und Navigation
  • Performance-Optimierung: Effiziente DOM-Manipulation und Inhaltsladung
  • User Experience Design: Sanfte Übergänge und intuitive Navigation

Nächste Stufe: Du bist bereit, moderne Frontend-Frameworks, fortgeschrittene Zustandsverwaltung zu erkunden oder komplexe Unternehmensanwendungen zu bauen!

🌟 Erfolg freigeschaltet: Du hast ein professionelles Fundament für Single-Page-Anwendungen mit modernen Web-Architekturmustern geschaffen!


GitHub Copilot Agent Challenge 🚀

Nutze den Agent-Modus, um die folgende Herausforderung abzuschließen:

Beschreibung: Verbessere die Banking-App, indem du Fehlerbehandlung und eine 404-Seitentemplate für ungültige Routen implementierst, um die Benutzererfahrung beim Navigieren zu nicht existierenden Seiten zu verbessern.

Aufgabe: Erstelle ein neues HTML-Template mit der ID "not-found", das eine benutzerfreundliche 404-Fehlerseite mit Styling anzeigt. Ändere dann die JavaScript-Routing-Logik so ab, dass dieses Template angezeigt wird, wenn Nutzer auf ungültige URLs navigieren, und füge eine "Go Home"-Schaltfläche hinzu, die zurück zur Login-Seite navigiert.

Erfahre mehr über den Agent-Modus.

🚀 Challenge

Füge ein neues Template und eine Route für eine dritte Seite hinzu, die die Credits dieser App anzeigt.

Ziele der Challenge:

  • Erstelle ein neues HTML-Template mit passender Inhaltsstruktur
  • Füge die neue Route zu deinem Routen-Konfigurationsobjekt hinzu
  • Integriere Navigationslinks zur und von der Credits-Seite
  • Teste dass alle Navigationen korrekt mit der Browserhistorie funktionieren

Post-Lecture Quiz

Post-Lecture Quiz

Rückblick & Selbststudium

Routing ist einer der überraschend schwierigen Teile der Webentwicklung, besonders da das Web sich von Seiten-Reload-Verhalten hin zu Single-Page-Application-Seiten-Reloads bewegt. Lies etwas darüber, wie der Azure Static Web App Service Routing handhabt. Kannst du erklären, warum einige der in diesem Dokument beschriebenen Entscheidungen notwendig sind?

Zusätzliche Lernressourcen:

  • Erkunde, wie populäre Frameworks wie React Router und Vue Router clientseitiges Routing implementieren
  • Untersuche die Unterschiede zwischen Hash-basiertem Routing und History API Routing
  • Lerne über Server-side Rendering (SSR) und wie es Routing-Strategien beeinflusst
  • Erforsche wie Progressive Web Apps (PWAs) Routing und Navigation handhaben

Aufgabe

Verbessere das Routing


Haftungsausschluss:
Dieses Dokument wurde mit dem KI-Übersetzungsdienst Co-op Translator übersetzt. Obwohl wir um Genauigkeit bemüht sind, beachten Sie bitte, dass automatisierte Übersetzungen Fehler oder Ungenauigkeiten enthalten können. Das Originaldokument in seiner Ursprungssprache ist als maßgebliche Quelle zu betrachten. Für wichtige Informationen wird eine professionelle menschliche Übersetzung empfohlen. Wir übernehmen keine Haftung für Missverständnisse oder Fehlinterpretationen, die aus der Nutzung dieser Übersetzung entstehen.