JavaScript Element pointerleave Event

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

What You’ll Learn

The pointerleave event fires when a pointer leaves an element’s hit-test area. Learn addEventListener vs onpointerleave, how it mirrors mouseleave, why it differs from pointerout, the pointerenter pair, and five try-it labs.

01

Kind

Instance event

02

Type

PointerEvent

03

When

Pointer leaves hit area

04

Handler

onpointerleave

05

Bubbles?

No (like mouseleave)

06

Status

Baseline widely available

Introduction

pointerleave answers: “Did a pointer just leave this element (and all descendants)?” It is the Pointer Events twin of mouseleave—unified for mouse, touch, and pen.

MDN notes that otherwise it works the same as mouseleave, and both are dispatched at the same time (with mouseout / pointerout when appropriate). Prefer the enter/leave pair for whole-component hover without descendant noise.

💡
Beginner tip

For pen devices, pointerleave also fires when the stylus leaves the hover range the digitizer can detect—not only when it leaves the element’s painted box on screen.

Understanding pointerleave

An instance event that answers: “Did the pointer leave this element tree?”

  • Hit test — fires when the pointer exits the element and all descendants.
  • Does not bubble — like mouseleave / unlike pointerout.
  • No descendant re-fire — moving among children does not fire leave on the parent.
  • Twin of mouseleave — dispatched together when mouse compatibility events apply.
  • Baseline Widely available on MDN (since July 2020).

📝 Syntax

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

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

onpointerleave = (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
relatedTargetElement the pointer entered (when available)

⚖️ pointerleave vs pointerout

Topicpointerleavepointerout
Bubbles?NoYes
Child boundariesIgnored for parent re-fireFires when moving among children
Mouse twinmouseleavemouseout
Enter twinpointerenterpointerover
Best forWhole-component hover exitDelegated / bubbling leave tracking

For most UI hover enter/exit, prefer pointerenter / pointerleave (or mouseenter / mouseleave) over the bubbling over/out pair.

🤳 Implicit Capture & Touch

On touchscreen browsers that allow direct manipulation, pointerdown can trigger implicit pointer capture. While capture is set, boundary events may be suppressed:

  • pointerover, pointerenter, pointerleave, and pointerout may not fire as expected.
  • Capture ends on pointerup / pointercancel, or when you call releasePointerCapture().
  • That is why a touch drag across neighbors may not look like mouse hover enter/leave.

⚡ Quick Reference

GoalCode / note
Listenel.addEventListener("pointerleave", fn)
Handler propertyel.onpointerleave = fn
Enter pairpointerenter
Bubbling alternativepointerover / pointerout
Mouse twinmouseleave (same timing when applicable)
MDN statusBaseline Widely available (Jul 2020)

🔍 At a Glance

Four facts to remember about pointerleave.

Event type
PointerEvent

MouseEvent + more

Means
left

Hit area + kids

Bubbles
false

Like mouseleave

Baseline
yes

Since Jul 2020

Examples Gallery

Examples follow MDN Element: pointerleave event. Move a mouse or pen onto the stage, then leave it (or lift after a touch).

📚 Getting Started

MDN listener patterns and the handler property.

Example 1 — Log pointerleave (MDN)

Fire when the pointer leaves the paragraph.

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

para.addEventListener("pointerleave", (event) => {
  out.textContent = "Pointer left element";
});
Try It Yourself

How It Works

The listener runs once when the pointer exits the element tree—not when moving among children.

Example 2 — onpointerleave Property (MDN)

Same idea using the handler property form.

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

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

How It Works

Prefer addEventListener when you need multiple listeners or easy removal.

📈 Compare, Hover & IDs

See why leave beats out for parents, pair with enter, and log device type.

Example 3 — pointerleave vs pointerout

Move among child boxes and compare fire counts on the parent.

JavaScript
const parent = document.getElementById("parent");
const out = document.getElementById("out");
let leaveCount = 0;
let outCount = 0;

parent.addEventListener("pointerleave", () => {
  leaveCount++;
  render();
});

parent.addEventListener("pointerout", () => {
  outCount++;
  render();
});

function render() {
  out.textContent =
    "pointerleave=" + leaveCount + " pointerout=" + outCount;
}
Try It Yourself

How It Works

pointerout fires at child boundaries; pointerleave waits until you leave the whole parent.

Example 4 — Hover Card with pointerenter

Show a tip on enter and hide it on leave—whole-component hover.

JavaScript
const card = document.getElementById("card");
const tip = document.getElementById("tip");

card.addEventListener("pointerenter", () => {
  tip.hidden = false;
  tip.textContent = "Preview details…";
});

card.addEventListener("pointerleave", () => {
  tip.hidden = true;
});
Try It Yourself

How It Works

Because enter/leave ignore descendant boundaries, the tip stays stable while you move over children inside the card.

Example 5 — Log pointerId and Type

See which device left the stage.

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

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

How It Works

Use pointerType when stylus hover-range exit should behave differently from mouse leave.

🚀 Common Use Cases

  • Whole-component hover exit for mouse, pen, and (where applicable) touch.
  • Hide previews, highlights, or tooltips without descendant flicker.
  • Pair with pointerenter instead of bubbling pointerover / pointerout.
  • Clear temporary UI state when the stylus leaves digitizer hover range.
  • Teach Pointer Events enter/leave vs the mouseenter/mouseleave twins.

🔧 How It Works

1

Pointer inside

Hotspot is over the element or a descendant (or pen is in hover range).

Inside
2

Crosses out

Pointer leaves the whole tree (or pen leaves digitizer hover range).

Boundary
3

pointerleave

Fires on the element; does not bubble; mouseleave may fire too.

Event
4

Clear hover UI

Hide tips, remove highlights, reset temporary state.

📝 Notes

  • MDN: Baseline Widely available (since July 2020) — no Deprecated / Experimental / Non-standard banner.
  • Does not bubble; pair with pointerenter for whole-component hover.
  • Dispatched with mouseleave when mouse compatibility events apply.
  • Implicit touch capture after pointerdown can suppress enter/leave until release.
  • Related learning: pointerenter, pointermove, mouseleave, addEventListener(), JavaScript hub.

Browser Support

pointerleave 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 pointerleave

Fires when a pointer leaves an element tree; does not bubble; pair with pointerenter for stable hover.

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
pointerleave Baseline

Bottom line: Use pointerenter / pointerleave for whole-component hover. Prefer pointerout only when you need bubbling.

Conclusion

pointerleave is the unified “pointer left this element tree” signal. Prefer it with pointerenter for stable hover on mouse, pen, and compatible touch paths.

Continue with pointermove, pointerenter, mouseleave, or the JavaScript hub.

💡 Best Practices

✅ Do

  • Use pointerenter + pointerleave for whole-component hover
  • Prefer them over pointerover / pointerout when descendants should not re-fire
  • Remember the mouse twins: mouseenter / mouseleave
  • Account for implicit touch capture during active contact
  • Clear temporary UI on leave (and on pointercancel for gestures)

❌ Don’t

  • Expect pointerleave to bubble to parents
  • Assume enter/leave will fire during every touch drag (capture may suppress them)
  • Replace CSS :hover with JS unless you need extra logic
  • Confuse it with pointerout child-boundary behavior
  • Overwrite onpointerleave if you need multiple listeners

Key Takeaways

Knowledge Unlocked

Five things to remember about pointerleave

Pointer left the element tree—non-bubbling hover exit for unified input.

5
Core concepts
📄02

PointerEvent

id · type · coords

API
03

vs pointerout

no bubble / no child noise

Compare
💡04

Pair

pointerenter

Pattern
🎯05

Baseline

since Jul 2020

Status

❓ Frequently Asked Questions

It fires when a pointing device moves out of the hit test boundaries of an element. For pen devices, it also fires when the stylus leaves the hover range detectable by the digitizer.
No. MDN marks Element pointerleave 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.
pointerleave does not bubble and is not sent again when the pointer moves between the element and its descendants. pointerout bubbles and fires when moving among descendants.
MDN notes that otherwise pointerleave works the same as mouseleave and they are dispatched at the same time (along with mouseout / pointerout when appropriate).
On touchscreen browsers with direct manipulation, pointerdown can trigger implicit pointer capture. While capture is set, pointerover / pointerenter / pointerleave / pointerout may not fire until release or releasePointerCapture.
Did you know?

Spec tables list pointerleave as non-bubbling and non-cancelable (no default action)—just like pointerenter. That is why parent listeners never see a bubbled leave from a child.

Next: pointermove

Learn the PointerEvent that fires when coordinates change.

pointermove →

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