Signatur
Beschreibung
XRSessionEvent erbt von Event und wird immer dann ausgelöst, wenn sich der Zustand einer XRSession ändert. Zusätzlich zu den geerbten Eigenschaften bietet das Objekt nur die schreibgeschützte Eigenschaft session. Sie verweist auf die XRSession, die das Ereignis ausgelöst hat.
In der Praxis bekommst du es bei zwei Ereignissen der XRSession:
end: Die Sitzung wurde beendet, entweder durchsession.end()oder durch den Nutzer bzw. das System (Headset abgesetzt, Systemmenü, Fehler). Hier gibst du Ressourcen frei, setzt den UI-Zustand zurück und zeigst den „VR starten“-Button wieder an.visibilitychange: Der Wert vonsession.visibilityStatehat sich geändert ("visible","visible-blurred","hidden"). Dann kannst du zum Beispiel die Spiellogik pausieren oder Eingaben ignorieren.
Weil das Ereignis die Sitzung direkt mitliefert, kann ein einziger Handler mehrere Sitzungen verwalten, ohne dass du eine globale Variable brauchst. Selbst erzeugen musst du ein XRSessionEvent fast nie. Das geht zwar mit dem Konstruktor new XRSessionEvent(type, init), ist aber hauptsächlich für Tests und Polyfills gedacht.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Konstruktor-Parameter: Name des Ereignisses, z. B. "end" oder "visibilitychange". |
|
| $eventInitDict Pflicht | XRSessionEventInit | Konstruktor-Parameter: Objekt mit der Pflicht-Eigenschaft session (XRSession) sowie den optionalen EventInit-Feldern bubbles, cancelable und composed (Standard jeweils false). |
|
| $session | XRSession | Instanz-Eigenschaft (nur lesbar): die XRSession, auf die sich das Ereignis bezieht. |
Rückgabewert
XRSessionEvent-Objekt zurück, dessen Eigenschaft session auf die übergebene Sitzung verweist.Beispiele
Aufräumen, wenn die VR-Sitzung endet
const button = document.querySelector('#enter-vr');
const onSessionEnded = (event) => {
// event ist ein XRSessionEvent
console.log('Sitzung beendet:', event.session.mode ?? 'immersive-vr');
event.session.removeEventListener('end', onSessionEnded);
button.textContent = 'VR starten';
button.disabled = false;
};
button.addEventListener('click', async () => {
if (!navigator.xr || !(await navigator.xr.isSessionSupported('immersive-vr'))) {
console.warn('Immersive VR wird nicht unterstützt.');
return;
}
const session = await navigator.xr.requestSession('immersive-vr');
session.addEventListener('end', onSessionEnded);
button.textContent = 'VR läuft …';
button.disabled = true;
});
Spiel pausieren bei geänderter Sichtbarkeit
const setupVisibilityHandling = (session, game) => {
session.onvisibilitychange = (event) => {
const state = event.session.visibilityState;
console.log('Sichtbarkeit:', state);
if (state === 'visible') {
game.resume();
} else {
// 'visible-blurred' (z. B. Systemmenü) oder 'hidden'
game.pause();
}
};
};
// Verwendung nach requestSession():
// setupVisibilityHandling(session, { pause: () => {}, resume: () => {} });
XRSessionEvent manuell erzeugen (z. B. in Tests)
const session = await navigator.xr.requestSession('inline');
session.addEventListener('end', (event) => {
console.log(event instanceof XRSessionEvent, event.session === session);
});
// Synthetisches Ereignis – beendet die Sitzung NICHT wirklich
const fakeEnd = new XRSessionEvent('end', { session });
session.dispatchEvent(fakeEnd);
// Wichtig · Fallstricke
- Kompatibilität: Die WebXR Device API wird vor allem von Chromium-Browsern (Chrome, Edge, Opera, Samsung Internet) und vom Meta Quest Browser unterstützt. Safari bietet sie nur auf visionOS an. In Firefox für Desktop ist sie nicht verfügbar. Prüfe deshalb vorher mit
'xr' in navigatorundnavigator.xr.isSessionSupported(). - Nur in sicheren Kontexten: Die API funktioniert nur über HTTPS (oder
localhost). Innerhalb von iframes muss außerdem die Permissions Policyxr-spatial-trackingerlaubt sein. - Ein selbst ausgelöstes
new XRSessionEvent('end', …)meldet nur ein Ereignis. Die Sitzung läuft dabei weiter. Beenden kannst du sie ausschließlich mitsession.end(). - Das Ereignis
endkommt auch dann, wenn System oder Nutzer die Sitzung beenden. Räume deshalb im Handler auf und nicht nur nach deinem eigenenend()-Aufruf. - Bei
visibilitychangemit dem Zustand"hidden"ruft der Browser keinerequestAnimationFrame-Rückrufe der Sitzung mehr auf. Verlasse dich in diesem Zustand also nicht auf deine Render-Schleife. XRSessionEventlässt sich nicht abbrechen und steigt nicht im DOM auf. Die Handler registrierst du direkt an derXRSession.