Signatur
Beschreibung
Das Ereignis pointerlockchange gehört zur Pointer Lock API. Es wird am Document ausgelöst, wenn ein Element per Element.requestPointerLock() den Zeiger erfolgreich sperrt oder wenn die Sperre wieder aufgehoben wird – durch document.exitPointerLock(), durch Drücken der Esc-Taste, durch einen Fenster-/Tab-Wechsel oder durch Entfernen des gesperrten Elements aus dem DOM.
Das Ereignis selbst verrät nicht, ob gesperrt oder entsperrt wurde. Den aktuellen Zustand liest man über document.pointerLockElement aus: Ist der Wert ein Element, ist der Zeiger gesperrt; ist er null, ist die Sperre aufgehoben. Das Ereignis ist ein einfaches Event ohne zusätzliche Eigenschaften, ist nicht abbrechbar und bubbelt nicht.
Typische Einsatzgebiete sind 3D-Spiele (First-Person-Steuerung), CAD- und Modellierungswerkzeuge sowie 360°-Viewer. Im Handler wird meist ein mousemove-Listener registriert oder entfernt, der über movementX/movementY relative Bewegungen auswertet, und die Oberfläche (z. B. ein „Klicken zum Spielen“-Overlay) angepasst.
Registrieren lässt sich das Ereignis per document.addEventListener("pointerlockchange", handler) oder über die Eigenschaft document.onpointerlockchange. Schlägt das Sperren fehl, wird stattdessen pointerlockerror ausgelöst.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignisname "pointerlockchange". |
|
| $handler Pflicht | (event: Event) => void | Callback, das bei jeder Änderung des Sperrzustands aufgerufen wird. Erhält ein generisches Event-Objekt. |
|
| $options | boolean | AddEventListenerOptions | false | Optionale Listener-Optionen wie once, signal oder capture. |
Beispiele
Sperrzustand per addEventListener überwachen
const canvas = document.querySelector('#game');
// Klick auf das Canvas fordert die Zeigersperre an
canvas.addEventListener('click', () => {
canvas.requestPointerLock();
});
const onMouseMove = (e) => {
console.log(`Δx: ${e.movementX}, Δy: ${e.movementY}`);
};
document.addEventListener('pointerlockchange', () => {
if (document.pointerLockElement === canvas) {
console.log('Zeiger gesperrt');
document.addEventListener('mousemove', onMouseMove);
} else {
console.log('Zeiger freigegeben');
document.removeEventListener('mousemove', onMouseMove);
}
});
Variante über die on-Property mit Pause-Overlay
const canvas = document.querySelector('#game');
const overlay = document.querySelector('#pause-overlay');
let paused = true;
overlay.addEventListener('click', () => canvas.requestPointerLock());
document.onpointerlockchange = () => {
paused = document.pointerLockElement !== canvas;
overlay.hidden = !paused;
console.log(paused ? 'Spiel pausiert' : 'Spiel läuft');
};
Listener mit AbortController wieder entfernen und Fehler abfangen
const canvas = document.querySelector('#viewer');
const controller = new AbortController();
const handleChange = () => {
const locked = document.pointerLockElement !== null;
canvas.classList.toggle('is-locked', locked);
console.log('Gesperrt:', locked);
};
document.addEventListener('pointerlockchange', handleChange, { signal: controller.signal });
document.addEventListener('pointerlockerror', () => {
console.warn('Zeigersperre konnte nicht aktiviert werden');
}, { signal: controller.signal });
canvas.addEventListener('click', async () => {
try {
// In neueren Browsern liefert requestPointerLock ein Promise
await canvas.requestPointerLock({ unadjustedMovement: true });
} catch (err) {
console.warn('Fehler:', err.name);
}
});
// Später, z. B. beim Verlassen der Ansicht:
const teardown = () => {
document.exitPointerLock();
controller.abort(); // entfernt beide Listener
};
// Wichtig · Fallstricke
- Kein Zustand im Event: Das Ereignis sagt nicht, ob gesperrt oder entsperrt wurde – immer
document.pointerLockElementprüfen. - Am Document registrieren: Das Ereignis wird am
Documentausgelöst, nicht am gesperrten Element. Ein Listener am Canvas bekommt nichts mit. - Nutzergeste erforderlich:
requestPointerLock()funktioniert nur als Reaktion auf eine Nutzerinteraktion (z. B. Klick). Nach einem Verlassen per Esc blockieren Chrome und andere Browser ein erneutes Sperren für etwa eine Sekunde – dann kommtpointerlockerrorstattpointerlockchange. - Promise-Rückgabe: Ab Chrome 92 / neueren Browsern gibt
requestPointerLock()ein Promise zurück; ältere Browser liefernundefined. Die OptionunadjustedMovementist nicht überall verfügbar. - Einschränkungen: In iframes ist das Sandbox-Attribut
allow-pointer-locknötig. Auf Mobilgeräten und Touch-only-Geräten wird die API meist nicht unterstützt. Alte Präfix-Varianten (mozpointerlockchange,webkitpointerlockchange) sind veraltet. - Den
mousemove-Listener bei Freigabe entfernen, um unnötige Verarbeitung und Speicherlecks zu vermeiden.