Signatur
Beschreibung
Das Interface HashChangeEvent beschreibt Ereignisse vom Typ hashchange. Sie werden am window-Objekt ausgelöst, sobald sich der Fragmentbezeichner der aktuellen URL ändert – etwa durch einen Klick auf einen Anker-Link (<a href="#abschnitt">), durch Setzen von location.hash oder durch Vor-/Zurück-Navigation zwischen Einträgen, die sich nur im Hash unterscheiden.
Zusätzlich zu den geerbten Eigenschaften von Event bietet das Interface zwei schreibgeschützte Eigenschaften:
oldURL– die vollständige URL vor der Änderung (alsstring).newURL– die vollständige URL nach der Änderung (alsstring).
Typische Einsatzgebiete sind einfache Hash-basierte Router in Single-Page-Anwendungen, Tab- oder Akkordeon-Steuerungen, deren Zustand in der URL gespeichert und damit verlinkbar ist, sowie das Nachverfolgen von Abschnitts-Navigation. Das Ereignis lässt sich per window.addEventListener("hashchange", handler) oder über die Eigenschaft window.onhashchange abonnieren.
Einen eigenen HashChangeEvent kann man mit dem Konstruktor new HashChangeEvent(type, options) erzeugen, etwa für Tests. Ein manuell ausgelöstes Ereignis ändert die URL jedoch nicht – es benachrichtigt lediglich die registrierten Listener.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Name des Ereignisses, üblicherweise "hashchange" (Groß-/Kleinschreibung beachten). |
|
| $options | object | {} | Optionales Wörterbuch; zusätzlich zu den Event-Optionen (bubbles, cancelable, composed). |
| $options.oldURL | string | "" | Wert für die Eigenschaft oldURL (vorherige URL). |
| $options.newURL | string | "" | Wert für die Eigenschaft newURL (neue URL). |
Rückgabewert
HashChangeEvent-Instanz mit den Eigenschaften oldURL und newURL.Beispiele
Hash-Änderungen mit addEventListener protokollieren
const onHashChange = (event) => {
console.log('Vorher:', event.oldURL);
console.log('Nachher:', event.newURL);
console.log('Aktueller Hash:', location.hash);
};
window.addEventListener('hashchange', onHashChange);
// Hash programmatisch ändern – löst das Ereignis asynchron aus
location.hash = '#kontakt';
// Später wieder abmelden:
// window.removeEventListener('hashchange', onHashChange);
Minimaler Hash-Router für eine Single-Page-App
const routes = {
'': () => '<h1>Startseite</h1>',
'produkte': () => '<h1>Produkte</h1>',
'kontakt': () => '<h1>Kontakt</h1>'
};
const render = () => {
const route = location.hash.slice(1); // '#produkte' -> 'produkte'
const view = routes[route] ?? (() => '<h1>404 – Seite nicht gefunden</h1>');
document.querySelector('#app').innerHTML = view();
};
// Über die on-Property registrieren
window.onhashchange = render;
// Beim ersten Laden ebenfalls rendern – hashchange feuert dabei NICHT
window.addEventListener('DOMContentLoaded', render);
Tab-Steuerung mit verlinkbarem Zustand
const activateTab = (id) => {
document.querySelectorAll('[role="tabpanel"]').forEach((panel) => {
panel.hidden = panel.id !== id;
});
};
window.addEventListener('hashchange', (event) => {
const newHash = new URL(event.newURL).hash.slice(1);
const oldHash = new URL(event.oldURL).hash.slice(1);
console.log(`Tab-Wechsel: ${oldHash || '(keiner)'} → ${newHash}`);
activateTab(newHash);
});
activateTab(location.hash.slice(1) || 'uebersicht');
Eigenes HashChangeEvent erzeugen (z. B. für Tests)
const event = new HashChangeEvent('hashchange', {
oldURL: 'https://example.com/#a',
newURL: 'https://example.com/#b'
});
console.log(event instanceof Event); // true
console.log(event.type, event.oldURL, event.newURL);
// Benachrichtigt Listener, ändert aber die URL nicht
window.dispatchEvent(event);
// Wichtig · Fallstricke
- Kein Ereignis beim Laden:
hashchangewird beim ersten Seitenaufruf nicht ausgelöst, auch wenn die URL bereits einen Hash enthält. Initialen Zustand daher separat auswerten. history.pushState()/replaceState()lösen keinhashchangeaus, selbst wenn sich nur der Hash ändert. Für History-basierte Navigation stattdessenpopstatenutzen (das beim Hash-Wechsel zusätzlich feuert).- Wird
location.hashauf den bereits aktuellen Wert gesetzt, feuert kein Ereignis. - Das Ereignis wird asynchron ausgelöst, ist nicht abbrechbar (
cancelable: false) und bubbelt amwindow. - Sicherheit: Der Hash ist vollständig vom Nutzer bzw. von fremden Links steuerbar. Werte aus
location.hashodernewURLniemals ungeprüft ininnerHTMLeinfügen oder aneval()übergeben – Gefahr von DOM-basiertem XSS. Mit Whitelists (wie im Router-Beispiel) arbeiten unddecodeURIComponent()beachten. - Kompatibilität: In allen modernen Browsern verfügbar (auch IE 8+ für das Ereignis;
oldURL/newURLerst ab IE 10 nicht vorhanden – dort fehlen sie). Der Konstruktor ist in aktuellen Browsern unterstützt.