Signatur
Beschreibung
PopStateEvent ist das Ereignisobjekt, das der Browser beim popstate-Ereignis an window übergibt. Das passiert, wenn der Nutzer mit Zurück oder Vor durch den Verlauf navigiert oder wenn history.back(), history.forward() oder history.go() aufgerufen wird. Voraussetzung ist, dass beide Einträge zum selben Dokument gehören, also mit history.pushState() oder history.replaceState() angelegt wurden oder sich nur im Fragment (#…) unterscheiden.
Die wichtigste Eigenschaft ist state. Sie enthält eine Kopie des Zustandsobjekts, das beim Anlegen des Verlaufseintrags an pushState() bzw. replaceState() übergeben wurde. Hat der Eintrag keinen Zustand (z. B. die erste Seite oder ein reiner Fragment-Wechsel), ist der Wert null. Mit state stellen Single-Page-Anwendungen die passende Ansicht wieder her, ohne die Seite neu zu laden.
Neuere Chromium-Browser haben außerdem die Eigenschaft hasUAVisualTransition (boolean). Sie zeigt an, ob der Browser bereits einen eigenen visuellen Übergang abgespielt hat, zum Beispiel eine Wischgeste auf Mobilgeräten. Dann kann die Anwendung ihre eigene Animation weglassen.
Man legt ein PopStateEvent normalerweise nicht selbst an. Mit dem Konstruktor new PopStateEvent(type, options) geht es aber, etwa für Tests oder um den eigenen Router nach pushState() manuell anzustoßen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Name des Ereignisses, in der Praxis immer "popstate". |
|
| $options | object | {} | Optionales Objekt mit den Feldern von EventInit (bubbles, cancelable, composed) sowie state (beliebiger Wert, Standard null) und hasUAVisualTransition (boolean, Standard false). |
Rückgabewert
PopStateEvent-Objekt (beim Konstruktor-Aufruf). Die schreibgeschützte Eigenschaft state hat den Typ any und enthält den Zustand des Verlaufseintrags oder null.Beispiele
Einfacher SPA-Router mit pushState und popstate
const render = (page) => {
document.querySelector('#app').textContent = `Seite: ${page}`;
};
const navigate = (page) => {
history.pushState({ page }, '', `/${page}`);
render(page);
};
window.addEventListener('popstate', (event) => {
// event ist ein PopStateEvent
console.log(event instanceof PopStateEvent, event.state);
render(event.state?.page ?? 'start');
});
navigate('produkte');
navigate('kontakt');
history.back(); // löst popstate asynchron aus
PopStateEvent manuell erzeugen und auslösen
window.onpopstate = (event) => {
console.log('Zustand:', event.state);
};
// pushState löst selbst KEIN popstate aus – bei Bedarf manuell anstoßen
history.pushState({ filter: 'neu' }, '', '?filter=neu');
const evt = new PopStateEvent('popstate', { state: history.state });
window.dispatchEvent(evt);
Browser-eigenen Übergang berücksichtigen
window.addEventListener('popstate', (event) => {
const view = event.state?.view ?? 'home';
if (event.hasUAVisualTransition) {
// Browser hat schon animiert (z. B. Wischgeste) – sofort umschalten
showView(view);
} else if (document.startViewTransition) {
document.startViewTransition(() => showView(view));
} else {
showView(view);
}
});
function showView(view) {
document.body.dataset.view = view;
console.log('Ansicht:', view);
}
Listener wieder entfernen
const onPop = (event) => console.log('Zurück zu', event.state);
window.addEventListener('popstate', onPop);
// z. B. beim Abbau einer Komponente
window.removeEventListener('popstate', onPop);
// Wichtig · Fallstricke
- Kein popstate bei pushState/replaceState: Diese Methoden lösen das Ereignis nicht aus. Es kommt nur bei echter Verlaufsnavigation (Zurück/Vor,
history.go()) oder bei Änderungen am Fragment. statekannnullsein: Beim ersten Eintrag und bei reinen Hash-Wechseln gibt es keinen Zustand. Deshalb immer abfangen, z. B. mitevent.state?.page ?? 'start'.- Nur klonbare Werte: Der Zustand wird mit dem Structured-Clone-Algorithmus kopiert. Funktionen, DOM-Knoten usw. sind nicht erlaubt und führen bei
pushState()zu einerDataCloneError-Ausnahme. Firefox begrenzt die Größe zudem auf ca. 16 MiB. - Kein Seiten-Reload: Der Browser ändert nur URL und Verlauf. Den Inhalt der Seite muss die Anwendung selbst neu aufbauen.
- Historische Unterschiede: Ältere Chrome- und Safari-Versionen haben
popstateauch beim ersten Laden der Seite ausgelöst. Heute tut das kein aktueller Browser mehr. - Kompatibilität:
PopStateEventundstatewerden von allen modernen Browsern unterstützt.hasUAVisualTransitiongibt es bisher nur in Chromium-Browsern, daher vorher prüfen. - Alternative: Die neuere Navigation API (
navigation.addEventListener('navigate', …)) ist für komplexe Router oft besser geeignet, wird aber noch nicht überall unterstützt.