Start · Sprachen · JavaScript · Referenz · Window.history

Window.history

Eigenschaft

Die schreibgeschützte Eigenschaft <code>Window.history</code> liefert das <code>History</code>-Objekt, mit dem sich die Session-Historie des aktuellen Tabs oder Frames lesen und verändern lässt.

seit JavaScript Baseline: alle Browser (pushState/replaceState sei Kategorie: webapi

Signatur

get Window.history

Beschreibung

window.history gibt eine Referenz auf das History-Objekt zurück. Darüber greifen Sie auf die Session-Historie zu, also auf die Seiten, die im aktuellen Tab oder Frame besucht wurden. Weil window das globale Objekt ist, schreibt man meistens einfach history.

Wichtige Bestandteile des Objekts:

  • history.back(), history.forward() und history.go(delta) navigieren in der Historie, genau wie die Vor- und Zurück-Schaltflächen des Browsers.
  • history.pushState(state, unused, url) legt einen neuen Eintrag an, ohne die Seite neu zu laden. history.replaceState() ersetzt dagegen den aktuellen Eintrag.
  • history.length gibt die Anzahl der Einträge an, history.state den Zustand des aktuellen Eintrags und history.scrollRestoration das Verhalten beim Wiederherstellen der Scroll-Position.

Die History-API ist die Grundlage für clientseitiges Routing in Single-Page-Applications. Die Anwendung ändert die URL mit pushState() und reagiert auf das Event popstate, wenn der Nutzer vor oder zurück navigiert.

Aus Sicherheitsgründen können Skripte die URLs anderer Einträge nicht auslesen. Sie können auch die Historie nicht löschen und die Zurück-Navigation nicht abschalten. Am nächsten kommt dem location.replace(): Diese Methode ersetzt den aktuellen Eintrag, statt einen neuen anzulegen.

Rückgabewert

Typ
History
Beschreibung
Eine Referenz auf das History-Objekt des aktuellen Browsing-Kontexts. Die Eigenschaft ist schreibgeschützt.

Beispiele

Zurück-Schaltfläche mit Rückfallziel

const backButton = document.querySelector('#back');

backButton.addEventListener('click', () => {
  // Gibt es einen vorherigen Eintrag in diesem Tab?
  if (window.history.length > 1) {
    history.back();
  } else {
    location.href = '/';
  }
});

Einfaches SPA-Routing mit pushState und popstate

const render = (path, state) => {
  document.querySelector('#app').textContent = `Seite: ${path} (id=${state?.id ?? '-'})`;
};

const navigate = (path, state = {}) => {
  history.pushState(state, '', path);
  render(path, state);
};

// Reagiert auf Vor- und Zurück-Navigation
window.addEventListener('popstate', (event) => {
  render(location.pathname, event.state);
});

navigate('/produkte/42', { id: 42 });
console.log(history.state);
{ id: 42 }

Filter in der URL speichern, ohne neuen Eintrag anzulegen

const updateFilter = (key, value) => {
  const url = new URL(location.href);
  url.searchParams.set(key, value);
  // replaceState vermeidet eine Flut von Historie-Einträgen
  history.replaceState({ ...history.state, [key]: value }, '', url);
};

updateFilter('sort', 'preis');
console.log(location.search);
?sort=preis

Scroll-Wiederherstellung selbst steuern

if ('scrollRestoration' in history) {
  history.scrollRestoration = 'manual';
}
console.log(history.scrollRestoration);
manual

// Wichtig · Fallstricke

  • Same-Origin-Regel: pushState() und replaceState() akzeptieren nur URLs mit demselben Ursprung. Andernfalls wird ein SecurityError geworfen. Der state muss strukturiert klonbar sein (keine Funktionen, keine DOM-Knoten) und darf nicht zu groß werden. Firefox erlaubt zum Beispiel etwa 16 MiB.
  • popstate: Das Event wird nicht durch pushState() oder replaceState() ausgelöst, sondern nur bei echter Navigation wie back(), forward(), go() oder den Browser-Schaltflächen. Bei einem Wechsel des Hashs feuert zusätzlich hashchange.
  • Server-Konfiguration: URLs, die mit pushState() gesetzt wurden, müssen auch beim direkten Aufruf oder beim Neuladen funktionieren. Der Server muss sie also z. B. auf die index.html umleiten, sonst kommt ein 404.
  • history.length gibt nur die Gesamtzahl der Einträge an. Sie verrät weder die Position des aktuellen Eintrags noch die URLs der anderen Einträge.
  • Der zweite Parameter von pushState() (title) wird von praktisch allen Browsern ignoriert. Übergeben Sie ''.
  • Browser drosseln sehr häufige Aufrufe von pushState() und replaceState(). Safari und Chrome erlauben ungefähr 100 Aufrufe in 10 Sekunden. Bei Scroll- oder Eingabe-Events sollten Sie die Aufrufe daher per Debounce bündeln.
  • Kompatibilität: Wird von allen modernen Browsern unterstützt. Für neue Projekte kommt in Chromium-Browsern zusätzlich die Navigation API (window.navigation) in Frage, die aber noch nicht in allen Browsern verfügbar ist.