Skip to content

Latest commit

 

History

28 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Pokédex

Eine Pokédex-Webanwendung mit Vanilla HTML, CSS und JavaScript – ohne Framework und ohne Build-Schritt. Die Daten kommen live von der PokéAPI.

Live-Demo: https://noubou1.github.io/Pokedex/

Pokédex Preview


Inhaltsverzeichnis


Features

  • Kartenübersicht – 20 Pokémon pro Ladeschritt, nachladbar per Button
  • Detail-Dialog – natives <dialog>-Element mit drei Tabs (Main, Stats, Artwork)
  • Base Stats – visuelle Fortschrittsbalken pro Statuswert
  • Typ-basiertes Design – Kartenfarbe und Icons richten sich nach dem Primärtyp
  • Live-Suche – filtert die geladenen Pokémon ab drei Zeichen, mit Enter-Support
  • Blättern im Dialog – vor und zurück durch die Liste, inklusive Umbruch an den Enden
  • Responsive – ein Layout für Desktop und Mobil
  • Tastatur- und Screenreader-tauglich – sichtbarer Fokus, ARIA-Labels, Esc schließt den Dialog
  • Fehler- und Leerzustände – bei API-Fehlern und ergebnisloser Suche erscheint eine Meldung

Technologien

Technologie Einsatz
HTML5 semantisches Markup, natives <dialog>
CSS3 Flexbox, Grid, Custom Properties, modular je Komponente
JavaScript (ES2021+) ES-Module, async/await, Event-Delegation
PokéAPI Datenquelle

Keine Abhängigkeiten, kein npm install, kein Bundler.


Lokal starten

Wichtig: Das Projekt nutzt ES-Module. Ein Öffnen per Doppelklick (file://) funktioniert deshalb nicht – der Browser blockiert Modul-Imports über das Dateiprotokoll. Es braucht einen lokalen HTTP-Server.

git clone https://github.com/NouBou1/Pokedex.git
cd Pokedex

Danach eine der folgenden Varianten:

# Variante A: Node.js
npx http-server -p 8000

# Variante B: Python
python -m http.server 8000

Variante C: In VS Code die Erweiterung Live Server installieren und „Go Live" klicken.

Anschließend http://localhost:8000 öffnen.


Projektstruktur

Pokedex/
├── index.html                  # Entry Point
├── style.css                   # Basis-Layout, Header, Helper-Klassen
├── css/
│   ├── button.css              # Buttons und Fokus-Styles
│   ├── card.css                # Kartenliste und Karte
│   ├── dialog.css              # Detail-Dialog und Tabs
│   ├── stats.css               # Stat-Balken
│   └── loader.css              # Ladeanzeige
├── js/
│   ├── main.js                 # Entry Point: Listener und Startladung
│   ├── config.js               # Konstanten, Typ- und Stat-Palette
│   ├── state.js                # App-Zustand (geladene Pokémon, Offset)
│   ├── api.js                  # PokéAPI-Requests
│   ├── format.js               # Rohdaten → anzeigbare Werte
│   ├── render.js               # DOM-Ausgabe
│   ├── dialog.js               # Verhalten des Detail-Dialogs
│   ├── search.js               # Namenssuche
│   └── templates/
│       └── template.js         # HTML-Templates
├── assets/
│   ├── icons/                  # Typ- und Button-Icons
│   └── img/                    # Logo, Hintergrund, Screenshot
└── fonts/
    └── pokemon-classic.ttf

Architektur

Jedes Modul hat genau eine Aufgabe, die Abhängigkeiten laufen nur in eine Richtung:

main.js ──► api.js ──► config.js
   │
   ├──► search.js ──┐
   ├──► dialog.js ──┼──► render.js ──► templates/template.js ──► format.js
   │                │        │
   └────────────────┴──► state.js
  • state.js ist die einzige Quelle der Wahrheit für die geladenen Pokémon. Kein Modul hält eine eigene Kopie der Liste.
  • templates/template.js enthält ausschließlich reine Funktionen, die HTML-Strings zurückgeben – kein DOM-Zugriff, kein Zustand.
  • render.js ist die einzige Stelle, die in das DOM schreibt.
  • Event-Delegation: Ein Listener auf der Kartenliste und einer auf dem Dialog bedienen alle – auch nachgeladene – Elemente. Im Markup steht kein einziges onclick.

Datenfluss

main.js: loadNextPage()
   └─► api.js: fetchPokemonPage(offset)      Index-Request, dann alle
        │                                    Detail-Requests via Promise.all
        └─► state.js: appendPokemon(page)
             └─► render.js: renderAllPokemonCards()
                  └─► template.js: getPokemonCardTemplate()

Genutzte Endpoints

GET https://pokeapi.co/api/v2/pokemon?limit=20&offset=0   # Liste
GET https://pokeapi.co/api/v2/pokemon/{id}                # Details

Was ich dabei gelernt habe

  • Paralleles Laden: Die Detail-Requests einer Seite laufen über Promise.all gleichzeitig statt sequenziell in einer await-Schleife. Das war der größte einzelne Performance-Gewinn im Projekt.
  • Das native <dialog>-Element: showModal() bringt Fokus-Falle und Backdrop mit. Wichtig ist, auf das close-Event zu hören statt nur auf den Close-Button – sonst bleibt beim Schließen per Esc der Scroll-Lock hängen.
  • Event-Delegation statt Inline-Handler: Bei nachgeladenen Karten müssen so keine Listener neu gebunden werden.
  • API-Einheiten prüfen: Die PokéAPI liefert Gewicht in Hektogramm und Größe in Dezimetern. Ungeprüft übernommen wiegt Bisasam 69 kg statt 6,9 kg.
  • Defensiv gegen fehlende Daten: Viele Pokémon haben kein home- oder dream_world-Sprite. Ohne Fallback entstehen kaputte Bildplatzhalter.

Ideen für Erweiterungen

  • Suche über den vollständigen Pokédex statt nur über die geladenen Einträge
  • Filter nach Typ und Generation
  • Favoriten via LocalStorage
  • Evolutions-Ketten im Detail-Dialog
  • Vergleichsmodus für zwei Pokémon

Lizenz

Der Code steht unter der MIT-Lizenz.

Pokémon sowie alle Namen, Bilder und Charaktere sind Eigentum von Nintendo, Game Freak und The Pokémon Company. Dieses Projekt ist ein nicht-kommerzielles Lernprojekt und steht in keiner Verbindung zu diesen Unternehmen. Die Daten stammen aus der PokéAPI, deren Fair-Use-Richtlinie gilt.


Autor

Noureddin Boussaada@NouBou1

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages