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
Fundamentals
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 mouseleaveevent (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.
Concept
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.
Foundation
📝 Syntax
The modern jQuery API for the mouseleave event has two main forms — binding a handler and triggering the event:
📋 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
Hands-On
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.
Pointer leaves #outer entirely → #log appends: "Handler for mouseleave called."
Moving from Outer into Inner child → handler does NOT fire
mouseleave fires only when exiting the bound element
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.
.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 );
} );
Left box (mouseout): leave counter increments when exiting outer AND inner child
Right box (mouseleave): leave counter increments only when exiting outer boundary
Move between outer and inner on left → count jumps; on right → stable
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).
Enter #nav-item → #submenu shows
Move into submenu links inside #nav-item → submenu stays open
Leave #nav-item entirely → mouseleave hides #submenu
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).
Enter a .card → .highlight class added (mouseenter)
Leave the card → .highlight removed (mouseleave)
Each card toggles independently — complete hover pair
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.
Applications
🚀 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.
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.
Important
📝 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.
Compatibility
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 ChromeAll versions · Desktop & Mobile
Full support
Mozilla FirefoxAll versions · Desktop & Mobile
Full support
Apple SafariAll versions · macOS & iOS
Full support
Microsoft EdgeAll versions · Chromium & Legacy
Full support
Internet ExplorerIE 6+ · Legacy environments
Full support
OperaAll modern versions
Full support
mouseleaveUniversal
Bottom line: Safe in any jQuery project. Prefer .on('mouseleave') over deprecated .mouseleave() for binding. Pair with mouseenter for stable hover menus.
Wrap Up
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.
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
Summary
Key Takeaways
Knowledge Unlocked
Six things to remember about the mouseleave event
Leave, hide, no bubble.
6
Core concepts
.on01
.on("mouseleave")
Bind
API
⚡02
.trigger()
Fire
Programmatic
out03
vs mouseout
No bubble
Compare
enter04
mouseenter
Pair
Hover
hide05
Hide UI
Menus
Pattern
.off06
.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).