Signatur
Beschreibung
Die schreibgeschützte Eigenschaft hashChange des NavigateEvent zeigt an, ob die laufende Navigation eine Fragmentnavigation ist. Das bedeutet: Die Ziel-URL unterscheidet sich von der aktuellen Dokument-URL nur im Fragment (dem Teil hinter #). Das Dokument bleibt geladen, der Browser springt höchstens zu einem Anker.
In Single-Page-Applications, die über navigation.addEventListener("navigate", …) das Routing selbst übernehmen, ist hashChange vor allem nützlich, um Sprungmarken-Navigationen nicht abzufangen. Klickt jemand auf einen Inhaltsverzeichnis-Link wie #kapitel-2, soll meist das normale Scrollen des Browsers greifen und kein Neuaufbau der Ansicht per event.intercept() passieren.
Der Wert wird beim Erzeugen des Events vom Browser festgelegt und lässt sich nicht ändern. Beim eigenen Erzeugen über new NavigateEvent(type, init) kann er über die Init-Option hashChange gesetzt werden (Standard: false).
Beispiele
Fragmentnavigationen im SPA-Router durchlassen
navigation.addEventListener('navigate', (event) => {
// Sprungmarken, Downloads und Cross-Origin-Ziele nicht abfangen
if (!event.canIntercept || event.hashChange || event.downloadRequest !== null) {
return;
}
const url = new URL(event.destination.url);
event.intercept({
async handler() {
const res = await fetch(`/partials${url.pathname}`);
document.querySelector('main').innerHTML = await res.text();
}
});
});
Hash-Änderungen protokollieren
navigation.addEventListener('navigate', (event) => {
const ziel = new URL(event.destination.url);
if (event.hashChange) {
console.log(`Sprung zu Abschnitt: ${ziel.hash}`);
} else {
console.log(`Neue Seite: ${ziel.pathname}`);
}
});
// Auslösen einer Fragmentnavigation
location.hash = 'kontakt';
Eigene Ansicht nur bei Hash-Routing aktualisieren
const zeigeTab = (name) => {
document.querySelectorAll('[data-tab]').forEach((el) => {
el.hidden = el.dataset.tab !== name;
});
};
navigation.addEventListener('navigate', (event) => {
if (!event.hashChange) return;
const tab = new URL(event.destination.url).hash.slice(1) || 'uebersicht';
event.intercept({
scroll: 'manual', // kein automatisches Springen zum Anker
handler: async () => zeigeTab(tab)
});
});
Synthetisches NavigateEvent mit hashChange
const ev = new NavigateEvent('navigate', {
destination: navigation.currentEntry, // nur zu Testzwecken
hashChange: true
});
console.log(ev.hashChange);
// Wichtig · Fallstricke
- Browser-Unterstützung: Die Navigation API gibt es seit Langem in Chrome/Edge/Opera (ab 102), erst seit Kurzem in Safari (26.2) und Firefox (147). Für ältere Browser per
if ('navigation' in window)prüfen und notfalls auf das Eventhashchangeanwindowausweichen. hashChangeist nurtrue, wenn sich ausschließlich das Fragment ändert. Ändern sich zusätzlich Pfad oder Query-String, ist der Wertfalse.- Geht die Navigation auf dieselbe URL mit demselben Hash (z. B. erneuter Klick auf
#top), gilt das trotzdem als Fragmentnavigation. - Auch bei Vor/Zurück-Navigationen (
navigationType === "traverse") zwischen Einträgen, die sich nur im Hash unterscheiden, ist der Werttrue. - Fängt man Fragmentnavigationen mit
intercept()ab, ohnescroll: "manual"zu setzen, scrollt der Browser nach dem Handler trotzdem zum Anker. Das ist meist gewollt, sollte aber bewusst entschieden werden. - Ein Wert von
trueheißt nicht automatisch, dasscanInterceptebenfallstrueist. Prüfe beides.