jQuery mouseleave Event

Beginner
⏱️ 11 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
Mouse events

What You’ll Learn

The mouseleave event fires when the mouse pointer leaves an element. This tutorial covers binding with .on("mouseleave"), triggering with .trigger("mouseleave"), comparing mouseleave with mouseout, pairing with mouseenter, and hiding menus and tooltips when the pointer exits.

01

.on()

Bind handler

02

.trigger()

Fire leave

03

vs out

No bubble

04

mouseenter

Pair enter

05

Hide UI

Menus

06

Since 1.7

Modern API

Introduction

Every hover interaction has an exit — dropdowns close, tooltips disappear, and highlight classes are removed when the pointer leaves. jQuery’s mouseleave event is the reliable way to run JavaScript at that moment, especially on elements that contain nested children.

The official jQuery API distinguishes the mouseleave event (bound with .on("mouseleave") since 1.7) from the deprecated .mouseleave() method used in older code. jQuery simulates mouseleave in every browser — the event was originally proprietary to Internet Explorer. To programmatically fire a handler, use .trigger("mouseleave") — available since jQuery 1.0.

Understanding the mouseleave Event

The mouseleave event is sent to an element when the mouse pointer leaves that element entirely. Unlike mouseout, it does not fire when the pointer moves from the parent into a child element inside the bound element — the handler runs only when exiting the outer boundary.

This non-bubbling behavior is why dropdown menus and tooltips prefer mouseleave paired with mouseenter. With mouseout, moving from a menu item into its submenu looks like leaving the parent — causing the menu to collapse before the user can click a submenu link.

💡
Beginner Tip

Always pair mouseleave with mouseenter — enter shows, leave hides. Moving between children inside a container does not trigger leave on the parent. For simple color-only hover effects, CSS :hover may be enough; use jQuery when you need to hide panels or run cleanup logic.

📝 Syntax

The modern jQuery API for the mouseleave event has two main forms — binding a handler and triggering the event:

1. Bind a handler — .on("mouseleave" [, eventData ], handler) (since 1.7)

jQuery
.on( "mouseleave" [, eventData ], handler )
  • eventData — optional object passed to the handler as event.data.
  • handler — function called each time mouseleave fires: function( event ) { ... }.

2. Event delegation — .on("mouseleave", selector, handler)

jQuery
$( "#menu" ).on( "mouseleave", "li", function( event ) {
  // runs when pointer leaves any li inside #menu
} );

3. Trigger the event — .trigger("mouseleave") (since 1.0)

jQuery
.trigger( "mouseleave" )
  • Runs bound mouseleave handlers on the matched element(s).
  • Use .triggerHandler("mouseleave") to run handlers without bubbling.

4. Unbind — .off("mouseleave" [, selector] [, handler])

jQuery
$( "#outer" ).off( "mouseleave" );              // remove all mouseleave handlers
$( "#menu" ).off( "mouseleave", "li", fn );     // remove delegated handler

Official jQuery API examples

jQuery
$( "#outer" ).on( "mouseleave", function() {
  $( "#log" ).append( " Handler for `mouseleave` called. " );
} );

$( "#other" ).on( "click", function() {
  $( "#outer" ).trigger( "mouseleave" );
} );

Return value

  • .on() and .trigger() return the original jQuery object for chaining.
  • Handler return values are ignored unless you use return false (equivalent to preventDefault() + stopPropagation()).

⚡ Quick Reference

GoalCode
Bind mouseleave handler$("#box").on("mouseleave", fn)
Pair enter and leave.on("mouseenter", show).on("mouseleave", hide)
Pass data to handler$("#box").on("mouseleave", { id: 1 }, fn)
Delegated mouseleave on children$("#menu").on("mouseleave", "li", fn)
Trigger mouseleave programmatically$("#outer").trigger("mouseleave")
Hide panel on leave$("#nav").on("mouseleave", function(){ $("#sub").hide(); })
Remove mouseleave handlers$("#box").off("mouseleave")

📋 mouseleave vs mouseout vs mouseenter vs CSS :hover

Four ways to respond when the pointer exits or moves over elements — choose the event that matches your hover needs.

mouseleave
exit once

Fires when pointer leaves bound element entirely — ignores child crossings; ideal for hiding menus

mouseout
bubbles

Re-fires on every child boundary crossing — can collapse menus when entering submenus

mouseenter
enter once

Fires when pointer enters bound element — pair with mouseleave for complete hover

CSS :hover
style only

Stylesheet pseudo-class — no JavaScript; use for simple color or visibility changes

Examples Gallery

Examples 1–3 follow the official jQuery API documentation. Examples 4–5 cover hiding UI on leave and the full enter/leave pair. Use the Try-it links to run each snippet in the browser.

📚 Binding & Triggering

Official jQuery demos for mouseleave handlers and programmatic triggers.

Example 1 — Official Demo: Bind Handler on #outer

Append a log message when the pointer leaves the outer element — the canonical .on("mouseleave") pattern.

jQuery
$( "#outer" ).on( "mouseleave", function() {
  $( "#log" ).append( " Handler for `mouseleave` called. " );
} );
Try It Yourself

How It Works

.on("mouseleave", fn) registers the function on #outer. jQuery calls it when the pointer crosses out of the outer boundary. Moving among children inside does not trigger leave — that is the key difference from mouseout.

Example 2 — Official Demo: #other Triggers mouseleave on #outer

One element programmatically fires the mouseleave handler on another.

jQuery
$( "#outer" ).on( "mouseleave", function() {
  $( "#log" ).append( " Handler for `mouseleave` called. " );
} );

$( "#other" ).on( "click", function() {
  $( "#outer" ).trigger( "mouseleave" );
} );
Try It Yourself

How It Works

.trigger("mouseleave") synthetically fires the mouseleave event on #outer, running the same handler as a physical pointer exit. Useful for testing hide behavior or keyboard-accessible fallbacks.

Example 3 — Official Demo: mouseout vs mouseleave

Side-by-side comparison — mouseout re-fires when leaving the inner child; mouseleave does not.

jQuery
var i = 0;
$( "div.overout" )
  .on( "mouseover", function() {
    $( "p", this ).first().text( "mouse over" );
  } )
  .on( "mouseout", function() {
    $( "p", this ).first().text( "mouse out" );
    $( "p", this ).last().text( ++i );
  } );

var n = 0;
$( "div.enterleave" )
  .on( "mouseenter", function() {
    $( "p", this ).first().text( "mouse enter" );
  } )
  .on( "mouseleave", function() {
    $( "p", this ).first().text( "mouse leave" );
    $( "p", this ).last().text( ++n );
  } );
Try It Yourself

How It Works

The official API demo uses nested divs with an inner yellow child. mouseout bubbles — crossing out of the inner div counts as a leave event on the parent. mouseleave ignores child crossings — the counter increments only when the pointer exits the entire outer box.

📈 Hide UI & Enter/Leave Pairs

Practical patterns for dropdowns, tooltips, and complete hover behavior.

Example 4 — Hide Submenu on mouseleave

Keep a dropdown open while the pointer is inside the nav item — hide it only when the pointer leaves the entire item (including nested submenu).

jQuery
$( "#nav-item" )
  .on( "mouseenter", function() {
    $( "#submenu" ).show();
  } )
  .on( "mouseleave", function() {
    $( "#submenu" ).hide();
  } );
Try It Yourself

How It Works

Binding on the parent #nav-item that wraps both the label and #submenu means moving between them does not fire leave. Only exiting the whole nav item triggers hide — the classic stable dropdown pattern.

Example 5 — Complete Hover: mouseenter + mouseleave on Cards

Add highlight on enter, remove on leave — the modern replacement for deprecated .hover(fnIn, fnOut).

jQuery
$( ".card" )
  .on( "mouseenter", function() {
    $( this ).addClass( "highlight" );
  } )
  .on( "mouseleave", function() {
    $( this ).removeClass( "highlight" );
  } );
Try It Yourself

How It Works

mouseenter handles the show half; mouseleave handles the hide half. Together they replace .hover(fnIn, fnOut) with explicit, readable event names — the recommended pattern in modern jQuery.

🚀 Common Use Cases

  • Close dropdowns$("#nav-item").on("mouseleave", function(){ $("#submenu").hide(); }).
  • Dismiss tooltips — hide the tooltip panel when the pointer leaves the trigger element.
  • Remove row highlight$("tr").on("mouseleave", fn) to reset table row styling.
  • Stop hover timers — clear a delayed-show timeout if the user leaves before it fires.
  • Pause previews — stop video or AJAX preview when the pointer exits the thumbnail.
  • Keyboard fallbacks$("#btn").on("blur", function(){ ... }).trigger("mouseleave") for accessibility parity.

🧠 How mouseleave Differs from mouseout

1

Pointer inside outer box

User hovers over the bound element — no leave event yet, even when moving among children.

inside
2

Pointer moves to child

mouseout fires on the parent. mouseleave stays silent — still inside the outer boundary.

child cross
3

Pointer exits entirely

User moves cursor completely outside the bound element — mouseleave fires. Hide menus, tooltips, or highlights.

mouseleave
4

Stable hide

Use mouseenter + mouseleave for menus with nested content — one enter, one leave, no premature collapse.

📝 Notes

  • Bind with .on("mouseleave", handler) since jQuery 1.7 — not the deprecated .mouseleave(handler) method.
  • Trigger with .trigger("mouseleave") since jQuery 1.0.
  • jQuery simulates mouseleave in all browsers — it was originally an IE proprietary event.
  • mouseleave does not fire when moving from parent into a child — unlike mouseout.
  • Always pair with mouseenter for complete hover behavior — not mouseover / mouseout.
  • Any HTML element can receive mouseleave — not limited to links or buttons.
  • Use .off("mouseleave") to remove handlers — avoid deprecated .unbind("mouseleave").
  • Touch devices have no true hover — provide click/tap fallbacks for critical UI.

Browser Support

jQuery simulates the mouseleave event in every browser it supports — the native event was originally IE-specific but is now widely available. jQuery’s .on("mouseleave") (since 1.7) and .trigger("mouseleave") (since 1.0) provide consistent cross-browser behavior.

jQuery 1.7+

jQuery mouseleave event

Supported in jQuery 1.x, 2.x, and 3.x across all modern browsers. Native equivalent: element.addEventListener('mouseleave', fn) — widely supported in current browsers; jQuery ensured parity in older IE. Adds collection binding, eventData, delegation, and .trigger().

100% With jQuery loaded
Google Chrome All versions · Desktop & Mobile
Full support
Mozilla Firefox All versions · Desktop & Mobile
Full support
Apple Safari All versions · macOS & iOS
Full support
Microsoft Edge All versions · Chromium & Legacy
Full support
Internet Explorer IE 6+ · Legacy environments
Full support
Opera All modern versions
Full support
mouseleave Universal

Bottom line: Safe in any jQuery project. Prefer .on('mouseleave') over deprecated .mouseleave() for binding. Pair with mouseenter for stable hover menus.

Conclusion

The jQuery mouseleave event fires when the pointer leaves an element entirely — once per exit, without firing when moving among nested children. Bind handlers with .on("mouseleave", fn), pair with .on("mouseenter", fn), and fire handlers programmatically with .trigger("mouseleave").

Choose mouseleave over mouseout when nested content would cause menus or tooltips to collapse prematurely. Use CSS :hover for simple styling. Replace deprecated .hover(fnIn, fnOut) with explicit enter and leave bindings. For touch devices, remember hover has no mobile equivalent — add click fallbacks where needed.

💡 Best Practices

✅ Do

  • Bind with .on("mouseleave", handler) — the modern, delegation-capable API
  • Pair mouseleave with mouseenter — not mouseover / mouseout
  • Bind leave on the container that wraps menu + submenu together
  • Use CSS :hover when only colors or visibility change
  • Call .off("mouseenter mouseleave") when removing hover behavior

❌ Don’t

  • Use deprecated .mouseleave(handler) for new code — use .on("mouseleave")
  • Swap mouseleave for mouseout on containers with nested submenus
  • Bind leave only on the menu label — not the wrapper that includes the submenu
  • Rely on hover alone for critical mobile UI — add tap/click fallbacks
  • Forget to unbind enter/leave handlers when tearing down SPAs

Key Takeaways

Knowledge Unlocked

Six things to remember about the mouseleave event

Leave, hide, no bubble.

6
Core concepts
02

.trigger()

Fire

Programmatic
out 03

vs mouseout

No bubble

Compare
enter 04

mouseenter

Pair

Hover
hide 05

Hide UI

Menus

Pattern
.off 06

.off("mouseleave")

Unbind

Cleanup

❓ Frequently Asked Questions

The mouseleave event fires when the mouse pointer leaves an element. In modern jQuery, bind handlers with .on('mouseleave', handler) since version 1.7. jQuery simulates this event across all browsers — it was originally proprietary to Internet Explorer. Any HTML element can receive mouseleave.
mouseleave fires only when the pointer exits the element it is bound to entirely — not when moving from the parent into a child inside it. mouseout bubbles and re-fires every time the pointer crosses a child boundary. For hover menus, tooltips, and dropdowns with nested content, mouseleave (paired with mouseenter) avoids menus collapsing when the user moves into a submenu.
Use CSS :hover when only colors, visibility, or simple styling change — no JavaScript required. Use jQuery mouseleave when you need to hide panels, stop timers, run animations, or execute logic CSS cannot express. For pure styling, prefer CSS; for behavior, use .on('mouseenter') and .on('mouseleave') in modern code.
Call .trigger('mouseleave') on the target element: $('#outer').trigger('mouseleave'). Available since jQuery 1.0, trigger runs bound mouseleave handlers. To run handlers without bubbling, use .triggerHandler('mouseleave') instead.
mouseenter fires when the pointer enters an element. mouseleave fires when the pointer leaves that same element entirely. Moving among children inside the bound element does not trigger mouseleave on the parent — only exiting the outer boundary does. Always pair them for complete hover behavior.
The deprecated .hover(handlerIn, handlerOut) method binds mouseenter and mouseleave in one call — handlerOut is the mouseleave handler. Under the hood, .hover() maps to those events, not a separate 'hover' event. For new code, use .on('mouseenter', fnIn).on('mouseleave', fnOut) instead of .hover().
Did you know?

The deprecated .hover(handlerIn, handlerOut) method maps handlerOut directly to mouseleave — there is no separate browser "hover" event. When you read legacy code like $("#menu").hover(showSub, hideSub), recognize that hideSub is a mouseleave handler. Migrating means splitting into .on("mouseenter", showSub).on("mouseleave", hideSub).

Next: .mouseleave() Method

Learn the deprecated shorthand — and how to migrate to .on("mouseleave").

.mouseleave() tutorial →

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