Adventskalender am 14. Dezember (es können alle Türchen vom 1. bis 14. Dezember geöffnet werden)
Aufbau Adventskalender
Der Adventskalender hat insgesamt 24 Türchen, die ähnlich wie die Radiosender beim Weihnachtsplayer angeklickt werden können. Hinter jedem Türchen verbirgt sich jedoch kein Radio-Stream, sondern ein Bild, welches vom Webserver aus einem geheimen oder für den Client nicht erreichbaren Ordner vom Webserver nachgeladen wird. Die Bilder werden alphabetisch sortiert und aufsteigend den Türchen 1 bis 24 zugewiesen. Sollten zu wenig Bilder im Ordner vorhanden sein, werden sie wiederverwendet. Die Türchen selbst werden in der Browseransicht zufällig verteilt, damit man länger suchen muss.
Hauptaugenmerk
In diesem Türchen soll vor allen die asynchrone Kommunikation zwischen Browser und Webserver vorgestellt werden. Fetch API ist eine moderne Möglichkeit, um asynchron die Bilder für den Adventskalender nachzuladen, ohne den Browser zu blockieren.
HTML, CSS, DOM und JavaScript
In dieser Anleitung wird das Wissen zum Weihnachtsplayer vorausgesetzt. Es wird erwartet, dass verstanden wurde, was HTML, CSS, DOM, JavaScript und Event Listener sind.
DOM
Code: Alles auswählen
<!DOCTYPE html>
html (lang="de")
│
├── head
│ │
│ ├── meta (charset="UTF-8")
│ ├── title ("Adventskalender")
│ ├── meta (name="viewport", content="width=device-width, initial-scale=1")
│ │
│ └── style
│ └── (CSS-Regeln für Layout und Responsive Design)
│
└── body
│
├── div#green-border
│ │
│ ├── h1
│ │
│ └── div.image-grid#imageGrid
│ │
│ ├── div.image-container
│ │ ├── div.door-number
│ │ └── img
│ │
│ └── ... (23 weitere div.image-container)
│
└── script
│
├── (Deklaration von Variablen und Funktionen)
Das DOM ist auf dem ersten Blick ähnlich aufgebaut wie der Weihnachtsplayer. Die Informationen zu den einzelnen Türchen werden beim Öffnen durch ein <img>-Objekt erweitert.
PHP-Bestandteile
Durch das Nachladen der Bilderliste und der einzelnen Bilder werden serverseitige Bestandteile und daher in diesem Fall PHP benötigt. Es handelt sich nicht um ein HTML-, sondern um ein PHP-Programm, welches unter dem Namen adventskalender.php auf einem Webserver gespeichert werden kann.
PHP-Initialisierung
Code: Alles auswählen
<?php
$currentDate = new DateTime();
$currentMonth = (int)$currentDate->format('n');
$currentDay = (int)$currentDate->format('j');
$imageDirectory = "SantasGeheimerOrdner";
Zu Beginn wird der Monat und der Tag ermittelt, damit nur die Türchen von 1 bis zum aktuellen Tag im Dezember geöffnet werden können. Die Bilder befinden sich aktuell in einem geheimen Bilderordner „SantasGeheimerOrdner“. Besser wäre die Verwendung eines Ordners außerhalb des öffentlich erreichbaren Webverzeichnisses.
PHP-Funktionen
Code: Alles auswählen
function SantasGetImage($day, $imageDirectory) {
[…]
}
function SantasServeImage($filename, $imageDirectory) {
[…]
}
Diese beiden Funktionen werden von Santa Claus nicht genauer betrachtet, da er noch Geschenke einpacken muss. Für sein Hauptthema Fetch API ist der Inhalt der Funktionen nicht direkt relevant.
PHP-Aufruf mit GET-Parameter
Code: Alles auswählen
if (isset($_GET['day'])) {
$day = intval($_GET['day']);
if ($day > 0 && $day <= 24 && $currentMonth == 12 && $day <= $currentDay) {
$image = SantasGetImage($day, $imageDirectory);
if ($image) {
SantasServeImage($image, $imageDirectory);
}
}
header("HTTP/1.0 404 Not Found");
exit;
}
HTML, HEAD, CSS, BODY und Beginn JavaScript
Code: Alles auswählen
<!DOCTYPE html>
<html lang="de">
<head>
[…]
</head>
<body>
<div id="green-border">
<h1>🎄 Adventskalender 🎄</h1>
<div class="image-grid" id="imageGrid"></div>
</div>
<script>
let images = [];
const currentMonth = <?php echo $currentMonth; ?>;
const currentDay = <?php echo $currentDay; ?>;
Auf CSS wird nicht genauer eingegangen. Zu Beginn wird ein grüner Rahmen und ein Gridsystem .imageGrid erstellt. JavaScript erhält den aktuellen Monat und den aktuellen Tag aus den serverseitigen PHP-Variablen, da sie innerhalb PHP sowieso benötigt werden. JavaScript könnte die Werte aber auch selbst berechnen. Ob das Bild ausgeliefert werden darf, entscheidet nicht der Browser, sondern der Server innerhalb von PHP.
Event Listener
Code: Alles auswählen
document.addEventListener('DOMContentLoaded', SantasInitializeAdventCalendar);
document.getElementById('imageGrid').addEventListener('click', function(event) {
const container = event.target.closest('.image-container');
if (container) {
SantasToggleCalendarDoor(container);
}
});
Nach Laden von DOM ('DOMContentLoaded') wird der Kalender initialisiert. Der zweite Event Listener steuert Click-Events auf den Adventskalender-Türchen.
Initialisierung Adventskalender
Code: Alles auswählen
function SantasInitializeAdventCalendar() {
const imageGrid = document.getElementById('imageGrid');
for (let i = 0; i < 24; i++) {
const imgContainer = document.createElement('div');
imgContainer.className = 'image-container';
imgContainer.dataset.number = i + 1;
const doorNumber = document.createElement('div');
doorNumber.className = 'door-number';
doorNumber.textContent = i + 1;
imgContainer.appendChild(doorNumber);
imageGrid.appendChild(imgContainer);
}
const containers = Array.from(imageGrid.children);
containers.sort(() => Math.random() - 0.5);
containers.forEach(container => imageGrid.appendChild(container));
}
Kalendertür öffnen und schließen
Code: Alles auswählen
async function SantasToggleCalendarDoor(container) {
const number = parseInt(container.dataset.number);
if (currentMonth === 12 && number <= currentDay) {
let img = container.querySelector('img');
if (!img) {
const imageUrl = `?day=${number}`;
try {
const response = await fetch(imageUrl);
if (!response.ok) throw new Error('Image not found');
const blob = await response.blob();
const objectURL = URL.createObjectURL(blob);
img = document.createElement('img');
img.src = objectURL;
container.appendChild(img);
} catch (error) {
console.error('Failed to load image:', error);
return;
}
}
if (img.style.display !== 'block') {
container.style.backgroundColor = 'transparent';
img.style.display = 'block';
img.style.border = '3px solid var(--border-color)';
} else {
container.style.backgroundColor = getComputedStyle(document.documentElement).getPropertyValue('--door-color');
img.style.display = 'none';
img.style.border = 'none';
}
}
}
Auszug Fetch API aus der Funktion SantasToggleCalendarDoor
Code: Alles auswählen
const response = await fetch(imageUrl);
if (!response.ok) throw new Error('Image not found');
const blob = await response.blob();
Geschlossenes Türchen
Code: Alles auswählen
<div class="image-container" data-number="5">
<div class="door-number">5</div>
</div>
Code: Alles auswählen
<div class="image-container" data-number="5">
<div class="door-number">5</div>
<img src="?day=5" style="display: block;">
</div>
Hat euch der Adventskalender von Santa Claus gefallen? Habt ihr zuhause auch einen Adventskalender? Oder habt ihr dieses Jahr nur den Debianforum Adventskalender und den Adventskalender von Santa Claus? Hat schon mal jemand von euch Fetch API, XMLHttpRequest oder eine andere Art von AJAX (Asynchronous JavaScript and XML) verwendet?-