JavaScript Document exitPointerLock() Method

Beginner
⏱️ 11 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
Limited availability
Instance method

What You’ll Learn

document.exitPointerLock() is an instance method that asynchronously releases pointer lock (see MDN Document: exitPointerLock()). Learn that it returns undefined, how it pairs with Element.requestPointerLock() and pointerLockElement, why you listen for pointerlockchange / pointerlockerror, and five try-it labs.

01

Kind

Instance method

02

Params

None

03

Returns

undefined

04

Releases

requestPointerLock

05

Track with

pointerlockchange

06

Status

Limited availability

Introduction

Pointer lock hides the system cursor and feeds raw mouse movement to a page — perfect for first-person games and 3D viewers. You lock with element.requestPointerLock(). To unlock from script, call document.exitPointerLock().

MDN: this method asynchronously releases a pointer lock previously requested through Element.requestPointerLock. Note the split API: request on an element, exit on the document.

💡
Think: unlock the mouse for your game canvas

1) Check document.pointerLockElement
2) If set, call document.exitPointerLock()
3) Listen for pointerlockchange (success path)
4) Also handle Esc — users can unlock without your button

Related tutorials: pointerLockElement, requestPointerLock(), exitFullscreen().

Understanding document.exitPointerLock()

An instance method on the page’s document object (Pointer Lock API; MDN).

  • Parameters — none (MDN).
  • Return valueundefined (MDN: None).
  • Async — release happens asynchronously; do not expect a Promise from this method (MDN).
  • Success / failure — listen for pointerlockchange and pointerlockerror (MDN).
  • Status — read document.pointerLockElement (non-null while locked).
  • User unlock — Esc typically releases the lock without your call.

📝 Syntax

General form of Document.exitPointerLock (MDN):

JavaScript
exitPointerLock()

Parameters

None (MDN).

Return value

None (undefined) (MDN).

Tracking the result (MDN)

Because there is no Promise, subscribe to document events:

JavaScript
document.addEventListener("pointerlockchange", () => {
  console.log(
    document.pointerLockElement
      ? "locked on " + document.pointerLockElement.id
      : "unlocked"
  );
});

document.addEventListener("pointerlockerror", () => {
  console.error("pointer lock failed");
});

if (document.pointerLockElement) {
  document.exitPointerLock();
}

⚡ Quick Reference

GoalCode
Unlockdocument.exitPointerLock()
Safe unlockif (document.pointerLockElement) document.exitPointerLock()
Lock firstel.requestPointerLock() (user gesture)
Listendocument.addEventListener("pointerlockchange", ...)
Feature-detecttypeof document.exitPointerLock === "function"
MDN statusLimited availability (not Baseline)

🔍 At a Glance

Four facts about document.exitPointerLock().

Returns
undefined

no Promise

Params
none

MDN

Track
pointerlockchange

+ error

Status
limited

Not Baseline

📋 Script unlock vs Esc

exitPointerLock()Esc / leave page
Who starts it?Your scriptThe user / browser
Return valueundefined (MDN)N/A
How to confirmpointerlockchange + pointerLockElementSame event fires
Best practiceGuard when locked; keep UI event-drivenNever assume only your Unlock button exits

Examples Gallery

Examples follow MDN Document: exitPointerLock() and practical Pointer Lock patterns. Locking usually needs a user gesture and a supporting desktop browser.

📚 Getting Started

Release lock and observe pointerlockchange.

Example 1 — Exit when locked

Call exitPointerLock() only if a lock target exists.

JavaScript
document.getElementById("unlock").addEventListener("click", () => {
  if (document.pointerLockElement) {
    document.exitPointerLock();
    console.log("exitPointerLock() called");
  } else {
    console.log("not locked");
  }
});
Try It Yourself

How It Works

MDN: exit is asynchronous and returns undefined. Confirm unlock on pointerlockchange, not from the method return value.

Example 2 — Sync UI on pointerlockchange

Update a label whenever lock is acquired or released.

JavaScript
const status = document.getElementById("status");

function updateStatus() {
  status.textContent = document.pointerLockElement
    ? "locked: " + document.pointerLockElement.id
    : "unlocked";
}

document.addEventListener("pointerlockchange", updateStatus);
updateStatus();

document.getElementById("unlock").addEventListener("click", () => {
  if (document.pointerLockElement) {
    document.exitPointerLock();
  }
});
Try It Yourself

How It Works

MDN requires listening for pointerlockchange to track success. Esc also fires this event when the user unlocks.

📈 Practical Patterns

Toggle controls, error handling, and feature detection.

Example 3 — Lock / unlock toggle

One button that requests lock or exits based on pointerLockElement.

JavaScript
const stage = document.getElementById("stage");

document.getElementById("toggle").addEventListener("click", () => {
  if (document.pointerLockElement === stage) {
    document.exitPointerLock();
  } else if (stage.requestPointerLock) {
    stage.requestPointerLock();
  }
});
Try It Yourself

How It Works

Request on the element, exit on the document — exactly the split MDN highlights. Prefer comparing to your target element, not only truthiness.

Example 4 — Listen for pointerlockerror

MDN: failures are reported with this event (not a returned Promise).

JavaScript
const out = document.getElementById("out");

document.addEventListener("pointerlockerror", () => {
  out.textContent = "pointerlockerror fired";
});

document.addEventListener("pointerlockchange", () => {
  out.textContent = document.pointerLockElement
    ? "locked"
    : "unlocked (or lock ended)";
});
Try It Yourself

How It Works

Unlike exitFullscreen() / exitPictureInPicture(), there is no Promise to catch. Wire both events early in your game UI.

Example 5 — Feature-detect before use

MDN marks Limited availability — check before shipping lock controls.

JavaScript
const canExit = typeof document.exitPointerLock === "function";
const canEnter =
  typeof Element !== "undefined" &&
  typeof Element.prototype.requestPointerLock === "function";

console.log({ canExit, canEnter });
Try It Yourself

How It Works

Hide Lock / Unlock buttons when either method is missing. Mobile and some environments may not support pointer lock well.

🚀 Common Use Cases

  • FPS / 3D games — Unlock when pausing or opening a menu.
  • Canvas viewers — Release lock when leaving orbit / look controls.
  • Toggle buttons — One control that locks or unlocks based on status.
  • Route / scene changes — Exit lock before navigating away.
  • Accessibility — Always offer Esc and a visible Unlock path.
  • Not a fullscreen exit — Use exitFullscreen() for fullscreen separately.

🧠 How exitPointerLock() Works

1

Pointer is locked

document.pointerLockElement points at the target element (or is null).

State
2

Script calls exitPointerLock()

No arguments; returns undefined. Release starts asynchronously (MDN).

Request
3

Events report the outcome

pointerlockchange on success/state change; pointerlockerror on failure (MDN).

Events
4

Cursor restored

pointerLockElement becomes null; normal mouse input resumes.

📝 Notes

  • MDN: Limited availability (not Baseline) — feature-detect in production.
  • MDN: no parameters; return value is undefined (not a Promise).
  • MDN: track success/failure with pointerlockchange and pointerlockerror.
  • MDN: request on an element; exit on the document.
  • Esc typically unlocks — keep UI event-driven.
  • Related: pointerLockElement, requestPointerLock(), exitFullscreen().

Browser Support

Document.exitPointerLock() is marked Limited availability on MDN (not Baseline). Feature-detect before production use. Logos use the shared browser-image-sprite.png sprite from this project.

Limited availability · Not Baseline

Document.exitPointerLock()

Asynchronously release pointer lock — pair with requestPointerLock, pointerLockElement, and pointerlockchange.

Limited Check compat
Google Chrome Supported · Desktop
Supported
Mozilla Firefox Supported in modern versions
Supported
Apple Safari Supported on desktop Safari
Supported
Microsoft Edge Chromium Pointer Lock support
Supported
Opera Follow Chromium behavior
Supported
Internet Explorer No Pointer Lock API
Not supported
Document.exitPointerLock() Limited availability

Bottom line: Call exitPointerLock when pointerLockElement is set. Confirm via pointerlockchange (no Promise). Feature-detect for Limited availability.

Conclusion

document.exitPointerLock() is the Pointer Lock API’s unlock switch: no parameters, returns undefined, and reports outcomes through events. Guard with pointerLockElement, listen for pointerlockchange, and remember Esc can unlock without your button.

Continue with pointerLockElement, getAnimations(), or the JavaScript hub.

💡 Best Practices

✅ Do

  • Check document.pointerLockElement before calling exit
  • Listen for pointerlockchange and pointerlockerror (MDN)
  • Request lock from a user gesture on the target element
  • Offer a visible Unlock control plus Esc support
  • Feature-detect both request and exit methods

❌ Don’t

  • Expect a Promise from exitPointerLock() (returns undefined)
  • Assume Baseline support on every device (MDN: Limited availability)
  • Forget Esc can unlock without your script
  • Confuse pointer lock with fullscreen or PiP exits
  • Call request on the document — request belongs on an element (MDN)

Key Takeaways

Knowledge Unlocked

Five things to remember about exitPointerLock()

Unlock asynchronously; confirm with events, not a return value.

5
Core concepts
🔄02

Async

via events

change / error
📄03

Guard

pointerLockElement

check
04

Pair

requestPointerLock

on element
🛡05

Status

Limited

not Baseline

❓ Frequently Asked Questions

MDN: Document.exitPointerLock() asynchronously releases a pointer lock previously requested through Element.requestPointerLock().
No. MDN does not mark Document.exitPointerLock() as Deprecated, Experimental, or Non-standard. It is Limited availability (not Baseline), so feature-detect in production.
None (undefined). MDN: it does not return a Promise. Track success or failure by listening for pointerlockchange and pointerlockerror.
MDN note: exitPointerLock() is called on the document, while requestPointerLock() is called on an element.
Check document.pointerLockElement. If it is non-null, that element is the lock target. It becomes null after a successful unlock.
Yes. Esc (and leaving the page) typically releases the lock. Listen for pointerlockchange so your UI stays in sync.
Did you know?

Fullscreen and PiP exits return Promises, but pointer lock exit does not. That historical quirk is why MDN insists on pointerlockchange / pointerlockerror instead of .then() — different APIs, different success signals.

Next: getAnimations()

Learn how to list and control every Animation on the document with getAnimations().

getAnimations() →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

6 people found this page helpful