149 lines
5 KiB
HTML
149 lines
5 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="de">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<meta name="description" content="API Demo – fetch & JSON – David & Karo EIS Projekt">
|
||
<title>API Demo – David & Karo</title>
|
||
<link rel="stylesheet" href="css/style.css">
|
||
<link rel="icon" href="img/logo.png" type="image/png">
|
||
</head>
|
||
<body>
|
||
<header>
|
||
<div class="header-container">
|
||
<div class="logo">
|
||
<img src="img/logo.png" alt="Logo">
|
||
<div class="logo-text">
|
||
<span class="institution">David & Karo</span>
|
||
<span class="project">EIS Projekt</span>
|
||
</div>
|
||
</div>
|
||
<!-- Begrüssung nach Tageszeit -->
|
||
<span id="begruessung" class="begruessung"></span>
|
||
<!-- Dark Mode Toggle Button -->
|
||
<button id="dark-mode-toggle" type="button" class="dark-mode-toggle" title="Dark Mode aktivieren">
|
||
<span class="dark-mode-icon">🌙</span>
|
||
</button>
|
||
<!-- Hamburger Menu Button (nur Mobile) -->
|
||
<button id="nav-toggle" type="button" class="nav-toggle" aria-label="Menü öffnen" aria-expanded="false">
|
||
<span></span><span></span><span></span>
|
||
</button>
|
||
<nav id="main-nav">
|
||
<a href="index.html">Start</a>
|
||
<a href="ueber_uns.html">Über uns</a>
|
||
<a href="eis_projekt.html">Projekt</a>
|
||
<a href="team.html">Team</a>
|
||
<a href="galerie.html">Galerie</a>
|
||
<a href="notenrechner.html">Notenrechner</a>
|
||
<a href="textanalyse.html">Textanalyse</a>
|
||
<a href="api.html" class="active">API Demo</a>
|
||
<a href="kanban.html">Kanban</a>
|
||
<a href="quiz.html">Quiz</a>
|
||
<a href="kontakt.html">Kontakt</a>
|
||
<a href="impressum.html">Impressum</a>
|
||
</nav>
|
||
</div>
|
||
</header>
|
||
|
||
<main>
|
||
<section class="hero">
|
||
<h1>🌐 fetch & API Demo</h1>
|
||
<p>Live-Daten von <code>jsonplaceholder.typicode.com/users</code> – geladen per JavaScript fetch(). ✨</p>
|
||
</section>
|
||
|
||
<section>
|
||
<h2>💡 Wie funktioniert's?</h2>
|
||
<div class="info-cards">
|
||
<div class="info-card">
|
||
<h4>1️⃣ fetch(URL)</h4>
|
||
<p>JavaScript sendet einen HTTP-GET Request an die API-URL und erhält eine Promise zurück.</p>
|
||
</div>
|
||
<div class="info-card">
|
||
<h4>2️⃣ .then(r => r.json())</h4>
|
||
<p>Die Antwort wird als JSON geparst – aus Text werden echte JavaScript-Objekte.</p>
|
||
</div>
|
||
<div class="info-card">
|
||
<h4>3️⃣ DOM rendern</h4>
|
||
<p>Die Daten werden mit <code>createElement</code> in den DOM eingefügt – kein Reload nötig!</p>
|
||
</div>
|
||
<div class="info-card">
|
||
<h4>4️⃣ .catch(err)</h4>
|
||
<p>Fehlerbehandlung: Falls die API nicht erreichbar ist, wird eine Fehlermeldung angezeigt.</p>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section>
|
||
<h2>👥 Benutzer von der API</h2>
|
||
<p>Die Liste wird live beim Laden der Seite von <strong>jsonplaceholder.typicode.com</strong> abgerufen:</p>
|
||
|
||
<div class="api-controls">
|
||
<button type="button" id="btn-reload" class="btn">🔄 Neu laden</button>
|
||
<input type="text" id="api-search" placeholder="🔍 Name oder Stadt filtern…" aria-label="Benutzer filtern">
|
||
</div>
|
||
|
||
<!-- Lade-Indikator -->
|
||
<div id="api-loading" class="api-loading">
|
||
<div class="api-spinner"></div>
|
||
<p>Daten werden geladen…</p>
|
||
</div>
|
||
|
||
<!-- Fehlermeldung -->
|
||
<div id="api-error" class="api-error" hidden>
|
||
<span>❌</span>
|
||
<div>
|
||
<strong>Fehler beim Laden der Daten.</strong><br>
|
||
<span id="api-error-msg"></span>
|
||
</div>
|
||
<button type="button" id="btn-retry" class="btn">Erneut versuchen</button>
|
||
</div>
|
||
|
||
<!-- Benutzer-Liste -->
|
||
<ul id="user-list" class="user-list" aria-live="polite"></ul>
|
||
|
||
<!-- Anzahl -->
|
||
<p id="user-count" class="api-count"></p>
|
||
</section>
|
||
|
||
<section>
|
||
<h2>📄 Quellcode-Erklärung</h2>
|
||
<pre class="code-block"><code>// 1. fetch aufrufen
|
||
fetch('https://jsonplaceholder.typicode.com/users')
|
||
|
||
// 2. Antwort als JSON parsen
|
||
.then(response => {
|
||
if (!response.ok) {
|
||
throw new Error('HTTP ' + response.status);
|
||
}
|
||
return response.json();
|
||
})
|
||
|
||
// 3. Daten in console.log prüfen & im DOM rendern
|
||
.then(users => {
|
||
console.log('API-Daten:', users);
|
||
renderUsers(users);
|
||
})
|
||
|
||
// 4. Fehlerbehandlung
|
||
.catch(error => {
|
||
console.error('Fetch-Fehler:', error);
|
||
showApiError(error.message);
|
||
});</code></pre>
|
||
</section>
|
||
</main>
|
||
|
||
<footer>
|
||
<p>© 2026 – Made with 💕 & ✨ – David & Karo</p>
|
||
<div class="footer-links">
|
||
<a href="impressum.html">Impressum</a>
|
||
<a href="kanban.html">Kanban</a>
|
||
<a href="quiz.html">Quiz</a>
|
||
<a href="kontakt.html">Kontakt</a>
|
||
<a href="#">Datenschutz</a>
|
||
</div>
|
||
</footer>
|
||
|
||
<script src="js/script.js"></script>
|
||
<script src="js/api-demo.js"></script>
|
||
</body>
|
||
</html>
|