The Document pointerlockchange event fires when the pointer is locked or unlocked (MDN). In the handler, read Document.pointerLockElement to see whether lock is active and which element owns it.
Register a listener with addEventListener. Check readiness and browser support before you rely on this event.
Syntax
Listen for pointerlockchange. Start with this line.
JavaScript
addEventListener("pointerlockchange", fn)
Call
What it does
addEventListener("pointerlockchange", fn)
Primary signature.
Built into the browser. Listen with document.addEventListener("pointerlockchange", …) — no import required.
Library declarations
JavaScript
addEventListener("pointerlockchange", fn)
Parameters
Parameter
Description
Listener on document
Required. Event does not bubble (MDN)
pointerLockElement
Required. Locked target, or null
Return Value
Return Value
Description
*
Fires as a Document event (listener receives the Event object).
JavaScript Examples
Example 1 — Listen on document
MDN style: after the change, read pointerLockElement to know lock state.
JavaScript
document.addEventListener("pointerlockchange", (event) => {
if (document.pointerLockElement) {
console.log("The pointer is locked to:", document.pointerLockElement);
} else {
console.log("The pointer is not locked");
}
});
console.log("Listener attached");
locked? true
/* then after Esc / exit: locked? false */
How It Works
Pick a stage element. That node becomes the lock target.
On click. If already locked, exit; otherwise request lock.
Need a gesture. Calling lock without a click often fails.
Confirm via the event.pointerlockchange reports the new state.
Example 3 — Feature Detection
Check support before offering a lock button.
JavaScript
const ok =
"pointerLockElement" in document &&
typeof document.documentElement.requestPointerLock === "function";
console.log("Pointer Lock usable:", ok);
if (!ok) {
console.log("Hide or disable the lock control");
}
Probe the property."pointerLockElement" in document is a quick signal.
Check the method. Confirm requestPointerLock exists.
Combine both. Only then treat the API as usable.
Degrade gracefully. Hide the control when support is missing.
Compatibility
Browser Support
Documentpointerlockchange is part of the Pointer Lock API. MDN marks it Limited availability (not Baseline). It is not Deprecated, Experimental, or Non-standard — still feature-detect in production.
✓ Limited availability · Not Baseline
Document pointerlockchange
Fires when the pointer is locked or unlocked. Read document.pointerLockElement for state.
LimitedFeature-detect required
Google ChromeSupported · Desktop & Mobile
Full support
Mozilla FirefoxSupported · Desktop & Mobile
Full support
Apple SafariSupported · macOS & iOS
Full support
Microsoft EdgeSupported · Chromium
Full support
Internet ExplorerNo native support · Use a polyfill
Polyfill
OperaSupported · Modern versions
Full support
Samsung InternetSupported · Android
Full support
Android WebViewSupported · Modern WebView
Full support
pointerlockchangeLimited
Bottom line: Works in many desktop browsers used for games, but support and policy vary. Always feature-detect, require a user gesture, and handle pointerlockerror.
Frequently Asked Questions
It fires when the pointer is locked or unlocked. In the handler, check document.pointerLockElement: if it is non-null the pointer is locked to that element; if null the pointer is not locked (MDN).
No. MDN does not mark it Deprecated, Experimental, or Non-standard. It has Limited availability (not Baseline), so feature-detect and test the browsers you care about.
No. MDN states the event is not cancelable and does not bubble. Listen on document.
Call element.requestPointerLock() from a user gesture to lock. Call document.exitPointerLock() or let the user press Esc to unlock. Update UI on pointerlockchange.
Listen for the pointerlockerror event on document. Failures often happen without a user gesture, in unsupported browsers, or when the browser denies permission.
Games and 3D viewers need unlimited mouse movement without hitting the screen edge. Locked input delivers movementX / movementY deltas instead of a visible cursor.