Listen aller Art sind ein wichtiger Bestandteil von Webseiten. Sie sollen schnell geladen werden und einfach zu bedienen sein. Einmal geladene Listenelemente sollen lokal gespeichert und wiederverwendet werden. Interaktionen mit den Listenelementen sollen in Echtzeit zwischen verschiedenen Tabs/Fenstern synchronisiert werden. Dieser Artikel zeigt, wie du das mit Web-Komponenten, einem Service-Worker und dem Session-Storage realisieren kannst.
Beispiel
Die folgenden zwei Listen zeigen die Verwendung von Web-Komponenten im Zusammenspiel mit einem Service-Worker und dem Session-Storage.
Voraussetzungen
Das Konzept der Web-Komponenten sollte dir bekannt sein. Ebenso solltest du wissen, wie ein Service-Worker funktioniert. Letzter verwenden wir jedoch nur zur Synchonisation der Klick-Events zwischen mehreren Listen und Browser-Tabs/-Fenstern.
Die grunlegende Funktionalität haben wir in eine separate Klasse ausgelagert. Diese Klasse wird in der default.js geladen und initialisiert.
Javascript: default.js// Load Extend Module
async function loadExtend(module) {
const file = './modules/' + module.charAt(0).toLowerCase() + module.slice(1) + '.js';
const mod = await import(file);
}
// Load List
async function loadList(element) {
if (document.querySelector(element)) {
await loadExtend('List');
}
}
// Do on DOM Ready
document.addEventListener('DOMContentLoaded', () => {
loadList('article-list');
});
Ich sammle die Extend-Module im Unterordner modules und nenne die Dateien wie die Klasse, aber mit Kleinbuchstaben beginnend. Die Klasse List befindet sich also in ./modules/list.js.
Die <article-list> ist ein benutzerdefiniertes Element. Die data-Parameter definieren das zu verwendende Template (articleCard) und die Daten (article1 bis article6). Diese Informationen werden vom Javascript gelesen und verarbeitet.
Das Template und die Daten werden aus dem Session-Storage geladen. Ist dort nichts vorhanden, werden sie vom Server geladen und im Session-Storage gespeichert.
PHP
Auf dem Server wird ein PHP-Skript benötigt, welches die Daten aus der Datenbank - in unserem Fall sind dies JSON-Dateien - holt und zurückgibt. Die list.js erwartet das PHP-Script unter /includes/data.php.
PHP: data.php<?php
// allow CORS
if(isset($_SERVER['HTTP_ORIGIN'])) {
header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Max-Age: 86400');
}
// set content type
header('Content-Type: application/json; charset=utf-8');
// verify the GET parameters
$data = isset($_GET['data']) ? $_GET['data'] : [];
if (!is_array($data)) {
$data = json_decode($data, true);
}
if (!is_array($data) || count($data) < 3) {
$response['error'] = 'Invalid GET parameters.';
echo json_encode($response);
exit;
}
$sessionId = $data[0];
$pool = $data[1];
$key = $data[2];
$value = isset($data[3]) ? $data[3] : null;
// check if session, pool and key are not empty
if ($sessionId == '' || $pool == '' || $key == '') {
$response['error'] = 'Session, Pool, and Key must not be empty.';
} else {
// check if the session exists
$sessionFile = 'users/'.$sessionId.'.json';
if (!file_exists($sessionFile)) {
$response['error'] = 'Session not found.';
} else {
// check if the pool exists
$poolFile = 'pools/'.$pool.'.json';
if (!file_exists($poolFile)) {
$response['error'] = 'Pool '.$pool.' not found.';
} else {
// check if the key exists
$poolData = json_decode(file_get_contents($poolFile), true);
if (!array_key_exists($key, $poolData)) {
$response['error'] = 'Key '.$key.' not found.';
} else {
// get data from file
if (!$value) {
foreach($poolData[$key] as $index => $content) {
$dataFile = 'components/'.$content;
if (file_exists($dataFile)) {
$poolData[$key][$index] = file_get_contents($dataFile);
}
}
$response['data'] = $poolData[$key];
} else {
// update data in file
$poolData[$key] = $value;
if (file_put_contents($poolFile, json_encode($poolData)) !== false) {
chmod($poolFile, 0666);
$response['success'] = $key.' updated.';
} else {
$response['error'] = $poolFile.' not saved.';
}
}
}
}
}
}
// send response
echo json_encode($response);
?>
JSON
Jetzt fehlen uns nur noch ein paar Musterdaten. Diese speichern wir in JSON-Dateien. Die Dateien liegen im Ordner /includes/pool/. Auch diese kannst du dir herunterladen.
Die Klick-Events werden über den Service-Worker synchronisiert. Dieser sendet die Events an alle geöffneten Tabs und Fenster, die dort über die items.js behandelt werden.
Javascript: service-worker.js// Process Message from Client
self.addEventListener('message', event => {
self.clients.matchAll().then(clients => {
clients.forEach(client => {
client.postMessage(event.data);
});
});
});
In unserem Beispiel wird das geklickte Item in allen Tabs/Fenstern grün markiert.
Dran bleiben
Du hast es geschafft. Abonniere meine Benachrichtigungen, um weitere News und Anleitungen von mir zu erhalten.