JavaScript Element pointerup Event

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

What You’ll Learn

The pointerup event fires when a pointer is no longer active. Learn addEventListener vs onpointerup, how it differs from mouseup, why you must also handle pointercancel, ending drag after setPointerCapture, and five try-it labs.

01

Kind

Instance event

02

Type

PointerEvent

03

When

Pointer no longer active

04

Handler

onpointerup

05

Alt end

pointercancel

06

Status

Baseline widely available

Introduction

pointerup answers: “Did this pointer just become inactive?” That covers mouse (last button released), touch (finger up), and pen (stylus lift) under one API.

Pair it with pointerdown to start/end gestures. MDN also reminds you that a gesture can end with pointercancel instead—clear state on both paths.

💡
Beginner tip

With a physical mouse, mouseup fires for every button release. pointerup fires only for the last button; releasing earlier buttons while others stay held does not fire pointerup.

Understanding pointerup

An instance event that answers: “Did this pointer just go inactive?”

  • Mouse — last held button released (not each earlier release).
  • Touch — contact ends (finger lifts).
  • Pen — stylus lifts from the digitizer.
  • Alt endpointercancel may replace a normal up.
  • Baseline Widely available on MDN (since July 2020).

📝 Syntax

Use the event name with addEventListener, or set the handler property:

JavaScript
addEventListener("pointerup", (event) => { });

onpointerup = (event) => { };

Event type

A PointerEvent (inherits from MouseEvent and Event).

Handy properties

PropertyMeaning
pointerIdUnique id for this pointer stream
pointerTypemouse, pen, touch, etc.
isPrimaryWhether this is the primary pointer of that type
clientX / clientYPointer position in the viewport
buttonsBitmask of buttons still pressed (often 0 after last release)

⚖️ pointerup vs Related Events

EventTypical use
pointerupPointer became inactive (last mouse button / lift)
mouseupEvery mouse button release (mouse-only legacy path)
pointerdownPointer became active (first button / contact)
pointercancelBrowser aborted the pointer; clear gesture state
clickFull activation; prefer for primary buttons/links

🚫 Always Pair with pointercancel

MDN: remember it is possible to get pointercancel instead of pointerup. Mobile browsers, stylus interruptions, and system gestures can abort a pointer mid-drag.

  • Share one endGesture() function for both up and cancel.
  • Release capture / CSS pressed states in that shared cleanup.
  • Do not assume every pointerdown gets a matching pointerup.

⚡ Quick Reference

GoalCode / note
Listenel.addEventListener("pointerup", fn)
Handler propertyel.onpointerup = fn
Identify pointerevent.pointerId, event.pointerType
End dragClear state on pointerup and pointercancel
vs mouseupLast button only for mouse
MDN statusBaseline Widely available (Jul 2020)

🔍 At a Glance

Four facts to remember about pointerup.

Event type
PointerEvent

MouseEvent + more

Means
inactive now

Normal release

vs mouseup
last button

Not every release

Baseline
yes

Since Jul 2020

Examples Gallery

Examples follow MDN Element: pointerup event. Press and release with a mouse, touch, or pen on the stage elements.

📚 Getting Started

MDN listener patterns and the handler property.

Example 1 — Log pointerup (MDN)

Fire when the pointer becomes inactive on the paragraph.

JavaScript
const para = document.querySelector("p");
const out = document.getElementById("out");

para.addEventListener("pointerup", (event) => {
  out.textContent = "Pointer up";
});
Try It Yourself

How It Works

The listener runs when the pointer goes inactive—after a press/contact ends normally.

Example 2 — onpointerup Property (MDN)

Same idea using the handler property form.

JavaScript
const para = document.querySelector("p");
const out = document.getElementById("out");

para.onpointerup = (event) => {
  out.textContent = "onpointerup at " + event.clientX + "," + event.clientY;
};
Try It Yourself

How It Works

Prefer addEventListener when you need multiple listeners or easy removal.

📈 IDs, Drag End & vs mouseup

Identify the pointer, finish capture drag, and compare fire rates with mouseup.

Example 3 — Log pointerId and Type

See which device and id became inactive.

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

stage.addEventListener("pointerup", (event) => {
  out.textContent =
    "up id=" + event.pointerId +
    " type=" + event.pointerType +
    " primary=" + event.isPrimary;
});
Try It Yourself

How It Works

Multi-touch UIs should clear session state keyed by pointerId.

Example 4 — End Drag on Up / Cancel

Capture on down; clear dragging on up and cancel.

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

handle.addEventListener("pointerdown", (event) => {
  handle.setPointerCapture(event.pointerId);
  handle.classList.add("is-dragging");
  out.textContent = "dragging id=" + event.pointerId;
});

function endDrag(label) {
  handle.classList.remove("is-dragging");
  out.textContent = label;
}

handle.addEventListener("pointerup", () => endDrag("released (pointerup)"));
handle.addEventListener("pointercancel", () => endDrag("aborted (pointercancel)"));
Try It Yourself

How It Works

Shared cleanup keeps pressed styles and capture state consistent whether the gesture ends normally or is aborted.

Example 5 — pointerup vs mouseup Counts

Hold multiple mouse buttons, then release them one by one.

JavaScript
const stage = document.getElementById("stage");
const out = document.getElementById("out");
let pointerCount = 0;
let mouseCount = 0;

stage.addEventListener("pointerup", () => {
  pointerCount++;
  render();
});

stage.addEventListener("mouseup", () => {
  mouseCount++;
  render();
});

function render() {
  out.textContent =
    "pointerup=" + pointerCount + " mouseup=" + mouseCount;
}
Try It Yourself

How It Works

MDN’s classic distinction: intermediate button releases produce more mouseup events, not more pointerup events.

🚀 Common Use Cases

  • End drag, draw, or resize sessions for mouse, touch, and pen.
  • Clear pressed / active feedback after release.
  • Drop setPointerCapture session state when the pointer goes inactive.
  • Branch by pointerType when stylus lift should behave differently.
  • Teach unified Pointer Events vs mouse-only mouseup.

🔧 How It Works

1

Pointer active

After pointerdown: buttons held / contact present.

Active
2

Release or abort

Last button up / lift, or the browser cancels the gesture.

End
3

pointerup or pointercancel

Normal inactive signal vs abort path.

Event
4

Clear gesture state

Remove pressed classes, end capture, finalize the action.

📝 Notes

  • MDN: Baseline Widely available (since July 2020) — no Deprecated / Experimental / Non-standard banner.
  • Primary UI actions: prefer click so keyboard users share the same path.
  • Clear gesture state on both pointerup and pointercancel.
  • Mouse multi-button: pointerup = last release only; mouseup = every release.
  • Related learning: pointerrawupdate, scroll, pointerdown, addEventListener(), JavaScript hub.

Browser Support

pointerup is marked Baseline Widely available on MDN (since July 2020). Logos use the shared browser-image-sprite.png sprite from this project. Pointer Events unify mouse, touch, and pen across modern engines.

Baseline · Widely available

Element pointerup

Fires when a pointer is no longer active; pair with pointercancel and prefer click for primary actions.

Full Widely available
Google Chrome Full support
Yes
Mozilla Firefox Full support
Yes
Apple Safari Full support
Yes
Microsoft Edge Full support
Yes
Opera Full support
Yes
Internet Explorer Pointer Events (legacy IE11 path)
Partial
pointerup Baseline

Bottom line: Use pointerup to end unified gestures. Remember the last-button difference vs mouseup on multi-button mice.

Conclusion

pointerup is the unified “pointer became inactive” signal. Use it to finish gestures started with pointerdown—and always clear state on pointercancel too.

Continue with scroll, pointerdown, pointercancel, or the JavaScript hub.

💡 Best Practices

✅ Do

  • Prefer pointerup to end unified mouse/touch/pen gestures
  • Clear state on both pointerup and pointercancel
  • Key multi-touch cleanup by pointerId
  • End capture/drag sessions on release
  • Prefer click for primary activate actions

❌ Don’t

  • Assume pointerup equals mouseup for multi-button mice
  • Forget the cancel path on mobile / stylus devices
  • Replace click with pointerup for primary buttons/links
  • Leave pressed CSS classes if cancel fires instead of up
  • Overwrite onpointerup if you need multiple listeners

Key Takeaways

Knowledge Unlocked

Five things to remember about pointerup

Pointer became inactive—one API for mouse, touch, and pen release.

5
Core concepts
📄02

PointerEvent

id · type · coords

API
👆03

vs mouseup

last button only

Compare
🚫04

Also cancel

clear both paths

Pattern
🎯05

Baseline

since Jul 2020

Status

❓ Frequently Asked Questions

It fires when a pointer is no longer active—for example when a mouse’s last held button is released, a finger lifts, or a stylus lifts from the digitizer.
No. MDN marks Element pointerup as Baseline Widely available (since July 2020). It is not Deprecated, Experimental, or Non-standard.
A PointerEvent (inherits from MouseEvent and Event). Useful fields include pointerId, pointerType, isPrimary, clientX, and clientY.
With a physical mouse, mouseup fires whenever any button is released. pointerup fires only on the last button release; releasing earlier buttons while others stay held does not fire pointerup.
Yes. MDN notes it is possible to get pointercancel instead of a normal pointerup—for example when the browser aborts the gesture. Always clear state on both paths.
Use it to end unified mouse/touch/pen gestures started with pointerdown (drag release, ink lift). Keep primary activate actions on click for keyboard accessibility.
Did you know?

Holding left and right mouse buttons, then releasing them one at a time, can produce two mouseup events but only one pointerup (the final release). That mirrors the first-button rule for pointerdown.

Next: scroll

Learn the event that fires when an element’s scroll position changes.

scroll →

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.

5 people found this page helpful