Adventskalender 14. Dezember 2024 - Fetch API - der Adventskalender von Santa Claus

Smalltalk
Antworten
uname
Beiträge: 12396
Registriert: 03.06.2008 09:33:02

Adventskalender 14. Dezember 2024 - Fetch API - der Adventskalender von Santa Claus

Beitrag von uname » 14.12.2024 06:17:30

Nachdem Santa Claus euch vor einigen Tagen seinen Weihnachtsplayer vorgestellt hat, folgt heute sein Adventskalender im Debianforum Adventskalender 2024. In wenigen Tagen zeigt er euch auch noch seine Schlitten-Navigationssoftware auf Basis der JavaScript-Bibliothek Leaflet für die Veteilung von Geschenken.

Adventskalender am 14. Dezember (es können alle Türchen vom 1. bis 14. Dezember geöffnet werden)

5234


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) {
[…]
}
Die serverseitig ausgeführten PHP-Funktionen SantasGetImage($day, $imageDirectory) sucht aus der Liste der Bilder im Bilderverzeichnis den Namen des Bildes für den angefragten Tag heraus. Hierbei wird die Liste der Bilder alphabetisch abgearbeitet und bei zu wenig Bildern wiederholt. Die PHP-Funktion SantasServeImage($filename, $imageDirectory) stellt das Bild mit dem Dateinamen $filename der aufrufenden JavaScript-Funktion und damit dem Browser zur Verfügung.

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;
}
Das Programm unterstützt die Verwendung des GET-Parameters „day“. Es wird das aufgerufene Bild mit dem Wert „day“ direkt an JavaScript und damit an den Browser zurückgegeben. Die in PHP und damit serverseitig enthaltenen Prüfungen stellen sicher, dass die Kalendertürchen nur bis zum aktuellen Tag geöffnet werden können. Der Befehl exit sowohl hier als auch in SantasServeImage($image, $imageDirectory) stellt sicher, dass in diesen Fällen das Hauptprogramm nicht erreicht wird. Das Hauptprogramm wird nur beim ersten Aufruf ohne Aufruf von GET-Parametern erreicht.


HTML, HEAD, CSS, BODY und Beginn JavaScript

Code: Alles auswählen

<!DOCTYPE html>
<html lang="de">
<head>
[…]
</head>
<body>
    <div id="green-border">
        <h1>&#127876; Adventskalender &#127876;</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));
    }
Der Kalender wird initialisiert. Hierbei werden die Kalendertürchen zufällig verteilt und dem DOM hinzugefügt.

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';
            }
        }
    }
Dieser Code ermöglicht durch das Click-Event den Wechsel des Kalendertürchens von „geschlossen“ zu „geöffnet“ und umgekehrt. Heute am 14.12.2024 lassen sich alle Türen von 1 bis 14 öffnen und wieder schließen. Die Türen 15 bis 24 lassen sich nicht öffnen. Das Bild wird als Binary Large Object (BLOB) dem Browser zurückgegeben.


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();
Die Fetch API ist eine moderne, asynchrone Methode für HTTP-Anfragen in JavaScript. Sie ersetzt zunehmend den älteren XMLHttpRequest (XHR). Es gibt aber weitere Alternativen auf die hier nicht eingegangen wird. Die Fetch API basiert auf Promises, was sie einfacher zu verwenden und zu verketten macht als XHR. JavaScript fragt beim Webserver die imageUrl z. B. „?day=14“ und damit das Bild des 14. Türchens ab. Das JavaScript läuft asynchron weiter, während der Webserver das Bild bereitstellt. Das Bild wird anschließend als Blob im Browser gespeichert und innerhalb von HTML bzw. DOM angezeigt.


Geschlossenes Türchen

Code: Alles auswählen

<div class="image-container" data-number="5">
    <div class="door-number">5</div>
</div>
Geöffnetes Türchen

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>
Um den Adventskalender zu verwenden, könnt ihr das Programm (NoPaste-Eintrag42267) in einen Ordner „adventskalender“ als „index.php“ speichern. In der aktuellen Version müsst ihr die Bilder im Unterordner „SantasGeheimerOrdner“ ablegen. Da die Bilder wiederverwertet werden, reicht testweise ein Bild.

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?-

uname
Beiträge: 12396
Registriert: 03.06.2008 09:33:02

Re: Adventskalender 14. Dezember 2024 - Fetch API - der Adventskalender von Santa Claus

Beitrag von uname » 18.12.2024 13:16:43

Ich habe beim Adventskalender von Santa Claus nun wie beim Weihnachtsplayer von Santa Claus eine schwarze Umrandung programmiert.

5245

Code: NoPaste-Eintrag42273

Antworten