Signatur
Beschreibung
Das storage-Ereignis wird am Window-Objekt ausgelöst, sobald ein anderes Dokument, das denselben Speicherbereich nutzt, einen Eintrag setzt, ändert, entfernt oder den Speicher leert. Das Fenster, das die Änderung selbst vornimmt, bekommt das Ereignis nicht. Genau deshalb eignet es sich gut, um mehrere offene Tabs derselben Anwendung abzugleichen, z. B. für Abmeldung in allen Tabs, Wechsel des Designs oder einen gemeinsamen Warenkorb.
Man kann den Handler auf zwei Arten registrieren: mit window.addEventListener("storage", handler) oder über die Eigenschaft window.onstorage = handler. Der Handler erhält ein StorageEvent mit den Eigenschaften key, oldValue, newValue, url und storageArea.
Bei localStorage teilen sich alle Tabs und Fenster desselben Ursprungs den Speicher. Bei sessionStorage gilt der Speicher nur innerhalb eines Tabs (Browsing-Kontext). Das Ereignis kommt dort also praktisch nur bei gleich-originären iframes innerhalb desselben Tabs an.
Das Ereignis lässt sich nicht abbrechen und steigt nicht auf (kein Bubbling). Wird clear() aufgerufen, sind key, oldValue und newValue jeweils null.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignisname "storage". |
|
| $handler Pflicht | (event: StorageEvent) => void | Callback, der ein StorageEvent erhält. |
|
| $event.key | string | null | Schlüssel des geänderten Eintrags, bzw. null bei clear(). |
|
| $event.oldValue | string | null | Bisheriger Wert, bzw. null, wenn der Eintrag neu ist. |
|
| $event.newValue | string | null | Neuer Wert, bzw. null, wenn der Eintrag entfernt wurde. |
|
| $event.url | string | URL des Dokuments, das die Änderung ausgelöst hat. | |
| $event.storageArea | Storage | null | Das betroffene Storage-Objekt (localStorage oder sessionStorage). |
Rückgabewert
addEventListener gibt nichts zurück.Beispiele
Änderungen aus anderen Tabs protokollieren
window.addEventListener("storage", (event) => {
if (event.storageArea !== localStorage) return;
console.log(`Schlüssel: ${event.key}`);
console.log(`Alt: ${event.oldValue} → Neu: ${event.newValue}`);
console.log(`Quelle: ${event.url}`);
});
// In einem ANDEREN Tab desselben Ursprungs ausführen:
// localStorage.setItem("theme", "dark");
Abmeldung in allen Tabs gleichzeitig
const logout = () => {
localStorage.setItem("logout", String(Date.now()));
window.location.href = "/login";
};
window.addEventListener("storage", (event) => {
if (event.key === "logout") {
// Anderer Tab hat sich abgemeldet → hier ebenfalls
window.location.href = "/login";
}
});
document.querySelector("#logout-btn")?.addEventListener("click", logout);
Über onstorage registrieren und wieder entfernen
const syncTheme = (event) => {
if (event.key === "theme" && event.newValue) {
document.documentElement.dataset.theme = event.newValue;
}
if (event.key === null) {
console.log("Speicher wurde geleert");
}
};
// Variante 1: on-Property
window.onstorage = syncTheme;
// Später abmelden
window.onstorage = null;
// Variante 2: addEventListener / removeEventListener
window.addEventListener("storage", syncTheme);
window.removeEventListener("storage", syncTheme);
JSON-Daten zwischen Tabs synchronisieren
const renderCart = (items) => console.log(`Warenkorb: ${items.length} Artikel`);
window.addEventListener("storage", ({ key, newValue }) => {
if (key !== "cart") return;
try {
const items = newValue ? JSON.parse(newValue) : [];
renderCart(items);
} catch {
console.warn("Ungültige Warenkorb-Daten");
}
});
// Anderer Tab:
// localStorage.setItem("cart", JSON.stringify([{ id: 1 }, { id: 2 }]));
// Wichtig · Fallstricke
- Nicht im auslösenden Tab: Das Fenster, das
setItem()aufruft, bekommt kein Ereignis. Die eigene Oberfläche muss man dort direkt aktualisieren. - Kein Ereignis ohne echte Änderung: Wird derselbe Wert erneut gesetzt, feuern die Browser in der Regel kein Ereignis. Soll trotzdem immer ein Signal ankommen (z. B. zum Abmelden), einen Zeitstempel als Wert verwenden.
- sessionStorage: Der Speicher gilt nur innerhalb eines Tabs. Das Ereignis erreicht daher nur gleich-originäre
iframes im selben Tab, keine anderen Tabs. - Nur Zeichenketten:
newValueundoldValuesind immer Strings odernull. JSON-Daten mittry/catchparsen. - Sicherheit: Werte aus dem Speicher können von jedem Skript desselben Ursprungs stammen, also auch von eingeschleustem Code. Sie nie ungeprüft in
innerHTMLschreiben (XSS-Gefahr). - Alternative: Für reine Nachrichten zwischen Tabs ist
BroadcastChanneloft sauberer, weil man dafür keinen Speicher „missbrauchen“ muss. - Browser-Kompatibilität: Wird von allen modernen Browsern unterstützt. Im privaten Modus oder bei deaktiviertem Speicher (z. B. blockierte Drittanbieter-Cookies in
iframes) kann der Zugriff auf den Speicher eine Ausnahme auslösen.