JavaScript Element setPointerCapture() Method

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

What You’ll Learn

Element.setPointerCapture() is an instance method that requests pointer capture for a given pointerId. Learn MDN’s horizontal slider demo, why capture keeps events flowing when the pointer leaves an element, how to pair with releasePointerCapture() and hasPointerCapture(), and five try-it labs aligned with MDN.

01

Kind

Instance method

02

Returns

undefined

03

Arg

pointerId

04

Action

Request capture

05

Events

Pointer

06

Status

Baseline widely

Introduction

Custom sliders, drag handles, and drawing tools need pointer events even when the user moves the mouse, finger, or pen outside the element. Without pointer capture, pointermove and pointerup may stop firing on your control once the pointer leaves its bounds.

element.setPointerCapture(pointerId) tells the browser: send all future events for this pointer to this element until capture is released (MDN). Call it on pointerdown, then call releasePointerCapture(pointerId) on pointerup or pointercancel.

💡
MDN slider pattern

Set capture when the user presses down, attach pointermove to slide the element, and release capture on pointerup. Add touch-action: none in CSS for smooth touch dragging.

This page is part of JavaScript Element. Prefer this over the deprecated setCapture() API for modern drag workflows.

Understanding the setPointerCapture() Method

Calling el.setPointerCapture(pointerId) designates this element as the capture target for that pointer (MDN).

  • It is an instance method on Element.
  • Takes one parameter: pointerId from a PointerEvent (MDN).
  • Returns undefined.
  • Throws NotFoundError if pointerId does not match any active pointer (MDN).
  • Capture ends automatically on pointerup, or call releasePointerCapture() explicitly.
  • Works with mouse, touch, and pen via the Pointer Events API.
  • Part of the Pointer Events specification (Baseline since July 2020).

📝 Syntax

General form of Element.setPointerCapture (MDN):

JavaScript
setPointerCapture(pointerId)

Parameters

ParameterTypeDescription
pointerIdnumberThe pointerId of a PointerEvent object (MDN).

Return value

undefined (MDN).

Exceptions

NotFoundError — Thrown if pointerId does not match any active pointer (MDN).

Common patterns

JavaScript
// MDN horizontal slider
const slider = document.getElementById("slider");

function beginSliding(e) {
  slider.onpointermove = slide;
  slider.setPointerCapture(e.pointerId);
}

function stopSliding(e) {
  slider.onpointermove = null;
  slider.releasePointerCapture(e.pointerId);
}

function slide(e) {
  slider.style.transform = `translate(${e.clientX - 70}px)`;
}

slider.onpointerdown = beginSliding;
slider.onpointerup = stopSliding;

⚡ Quick Reference

GoalCode
Request captureel.setPointerCapture(id)
On pointerdownel.setPointerCapture(ev.pointerId)
Check captureel.hasPointerCapture(id)
Release captureel.releasePointerCapture(id)
Feature detecttypeof el.setPointerCapture === "function"
Touch CSStouch-action: none

🔍 At a Glance

Four facts to remember about Element.setPointerCapture().

Returns
undefined

No value

Arg
pointerId

From event

Purpose
capture

Keep events

Status
baseline

Jul 2020

📋 Pointer capture APIs

setPointerCapture()releasePointerCapture()setCapture()
ActionRequest captureRelease captureLegacy mouse capture
StandardPointer Events (MDN)Pointer EventsDeprecated, Non-standard
Input typesMouse, touch, penMouse, touch, penMouse only (Gecko)
Typical callpointerdownpointerupmousedown
Best forModern drag UIsEnd drag / cleanupLegacy code only

Examples Gallery

Examples follow MDN Element.setPointerCapture() patterns. Use View Output or Try It Yourself for each case.

📚 Getting Started

MDN horizontal slider — capture on pointerdown.

Example 1 — MDN Horizontal Slider

Set capture on press so the slider keeps receiving pointermove outside its box (MDN).

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

function beginSliding(e) {
  slider.onpointermove = slide;
  slider.setPointerCapture(e.pointerId);
}

function stopSliding(e) {
  slider.onpointermove = null;
  slider.releasePointerCapture(e.pointerId);
}

function slide(e) {
  slider.style.transform = `translate(${e.clientX - 70}px)`;
}

slider.onpointerdown = beginSliding;
slider.onpointerup = stopSliding;
Try It Yourself

How It Works

MDN: setPointerCapture(e.pointerId) in beginSliding routes future pointer events to the slider until releasePointerCapture on pointerup.

Example 2 — Capture on pointerdown

Request capture at the start of any drag interaction.

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

box.addEventListener("pointerdown", (ev) => {
  box.setPointerCapture(ev.pointerId);
  console.log("capture requested for pointer", ev.pointerId);
});

box.addEventListener("pointerup", (ev) => {
  box.releasePointerCapture(ev.pointerId);
  console.log("capture released");
});
Try It Yourself

How It Works

Always use the same event.pointerId for both setPointerCapture and releasePointerCapture.

📈 Practical Patterns

Drag outside bounds, verify capture, and touch-friendly CSS.

Example 3 — Drag Outside Element Bounds

Without capture, pointermove stops when the pointer leaves the box.

JavaScript
const handle = document.getElementById("handle");
let offsetX = 0;

handle.addEventListener("pointerdown", (ev) => {
  offsetX = ev.clientX - handle.offsetLeft;
  handle.setPointerCapture(ev.pointerId);
});

handle.addEventListener("pointermove", (ev) => {
  if (!handle.hasPointerCapture(ev.pointerId)) return;
  handle.style.left = (ev.clientX - offsetX) + "px";
});

handle.addEventListener("pointerup", (ev) => {
  handle.releasePointerCapture(ev.pointerId);
});
Try It Yourself

How It Works

Capture is the key reason custom drags work reliably. The handle receives pointermove until you release capture (MDN).

Example 4 — Verify with hasPointerCapture()

Confirm capture is active after calling setPointerCapture().

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

knob.addEventListener("pointerdown", (ev) => {
  knob.setPointerCapture(ev.pointerId);
  console.log("has capture:", knob.hasPointerCapture(ev.pointerId)); // true
});
Try It Yourself

How It Works

Use hasPointerCapture() to guard pointermove handlers and avoid acting on unrelated pointers.

Example 5 — Touch Sliders with touch-action: none

Combine capture with CSS so touch dragging does not scroll the page (MDN).

JavaScript
#slider {
  touch-action: none; /* prevent browser scroll while dragging */
}
JavaScript
const slider = document.getElementById("slider");

slider.addEventListener("pointerdown", (ev) => {
  slider.setPointerCapture(ev.pointerId);
});

slider.addEventListener("pointerup", (ev) => {
  slider.releasePointerCapture(ev.pointerId);
});
Try It Yourself

How It Works

MDN’s slider example uses touch-action: none on the draggable element. Pair it with setPointerCapture for reliable touch and pen input.

🚀 Common Use Cases

  • Horizontal and vertical sliders (MDN demo).
  • Custom drag handles that must track outside element bounds.
  • Drawing pads and signature capture UIs.
  • Resizable panels and split views.
  • Replacing deprecated setCapture() in legacy drag code (MDN).
  • Touch-friendly controls with touch-action: none (MDN).

🧠 How setPointerCapture() Routes Events

1

User presses pointer

pointerdown fires with a unique pointerId (MDN).

pointerdown
2

Request capture

element.setPointerCapture(event.pointerId) designates the capture target (MDN).

Capture
3

Events stay on element

pointermove and pointerup target the capture element even outside its bounds.

Route
4

Release on pointerup

Call releasePointerCapture(pointerId) or let pointerup end capture automatically.

📝 Notes

  • Not Deprecated, Experimental, or Non-standard on MDN (Baseline Widely available, July 2020).
  • Requires a valid pointerId from an active PointerEvent (MDN).
  • Throws NotFoundError if pointerId does not match any active pointer.
  • Always pair with releasePointerCapture() on pointerup or pointercancel.
  • Use touch-action: none on draggable elements for touch sliders (MDN).
  • Related: hasPointerCapture(), releasePointerCapture(), setCapture() (deprecated), JavaScript hub.

Browser Support

Element.setPointerCapture() is Baseline Widely available (MDN: across browsers since July 2020). Logos use the shared browser-image-sprite.png sprite from this project.

Baseline Widely available

Element.setPointerCapture()

Request pointer capture for a pointerId — essential for drag, slider, and drawing UIs.

Baseline Widely available
Google Chrome Supported · Desktop & Mobile
Yes
Microsoft Edge Supported · Chromium
Yes
Mozilla Firefox Supported · Desktop & Mobile
Yes
Apple Safari Supported · macOS & iOS
Yes
Opera Supported · Modern versions
Yes
Internet Explorer Not supported
No
setPointerCapture() Excellent

Bottom line: Use setPointerCapture() on pointerdown and releasePointerCapture() on pointerup. Add touch-action: none for touch sliders. Prefer over deprecated setCapture().

Conclusion

Element.setPointerCapture() keeps pointer events on your element during drags and sliders. MDN’s pattern: capture on pointerdown, handle pointermove, release on pointerup.

Continue with releasePointerCapture(), hasPointerCapture(), or the JavaScript hub.

💡 Best Practices

✅ Do

  • Call setPointerCapture on pointerdown (MDN)
  • Release with the same pointerId on pointerup
  • Add touch-action: none for touch sliders (MDN)
  • Handle pointercancel for interrupted touches
  • Use hasPointerCapture() to guard move handlers

❌ Don’t

  • Use deprecated setCapture() in new code
  • Forget to release capture after drag ends
  • Call with stale or wrong pointerId values
  • Assume mouse-only — test touch and pen too
  • Skip touch-action: none on mobile sliders

Key Takeaways

Knowledge Unlocked

Five things to remember about Element.setPointerCapture()

Request capture — keep pointer events during drag and slider interactions.

5
Core concepts
👆 02

Arg

pointerId

Event
🎯 03

Capture

request

Route
📈 04

Pair

release

Cleanup
🌐 05

Support

baseline

Jul 2020

❓ Frequently Asked Questions

It designates an element as the capture target for future pointer events. Subsequent events for that pointer are targeted at the capture element until capture is released via releasePointerCapture() or pointerup (MDN).
No. MDN marks Element.setPointerCapture() as Baseline Widely available (across browsers since July 2020). It is not Deprecated, Experimental, or Non-standard.
undefined. There is no return value (MDN).
The pointerId from a PointerEvent object — typically event.pointerId from pointerdown, pointermove, or pointerup (MDN).
On pointerdown when starting a drag, slider, or custom control so pointermove and pointerup still reach your element even if the pointer leaves its bounds (MDN).
MDN: NotFoundError if pointerId does not match any active pointer.
Did you know?

MDN recommends setPointerCapture() as the modern replacement for the deprecated Gecko-only setCapture() method. Pointer capture works across mouse, touch, and pen with the same pointerId API.

Next: releasePointerCapture()

Learn how to stop pointer capture when your drag or slider interaction ends.

releasePointerCapture() →

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.

8 people found this page helpful