jQuery mouseover Event

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

What You’ll Learn

The mouseover event fires when the mouse pointer enters an element. This tutorial covers binding with .on("mouseover"), triggering with .trigger("mouseover"), understanding bubbling and event.relatedTarget, comparing mouseover with mouseenter, and when to prefer mouseenter for nested menus.

01

.on()

Bind handler

02

.trigger()

Fire over

03

bubbles

Child crosses

04

relatedTarget

Filter false

05

mouseout

Legacy pair

06

Since 1.7

Modern API

Introduction

Every hover interaction has an entry — dropdowns open, tooltips appear, and highlight classes are added when the pointer enters. jQuery’s mouseover event is the classic way to run JavaScript at that moment, but its bubbling behavior can surprise developers working with nested elements.

The official jQuery API distinguishes the mouseover event (bound with .on("mouseover") since 1.7) from the deprecated .mouseover() method used in older code. Unlike mouseenter, mouseover bubbles — it fires when entering the bound element or when moving from the parent into a child inside it. To programmatically fire a handler, use .trigger("mouseover") — available since jQuery 1.0.

Understanding the mouseover Event

The mouseover event is sent to an element when the mouse pointer enters that element. Because it bubbles, moving from a parent into a child inside the bound element also triggers mouseover on the parent — the event trickles up the DOM tree just like a physical entry on every child boundary.

This bubbling behavior causes headaches with nested menus and tooltips. When the pointer moves from a menu item into its submenu, mouseover fires on the parent container again — making it look like the user entered the menu from outside. For nested content, jQuery recommends mouseenter paired with mouseleave instead. If you must use mouseover, inspect event.relatedTarget to filter false positives.

💡
Beginner Tip

For hover menus with submenus, prefer mouseenter + mouseleave over mouseover + mouseout. If you inherit legacy mouseover code on nested elements, check event.relatedTarget — when the pointer came from inside the bound container, ignore the event.

📝 Syntax

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

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

jQuery
.on( "mouseover" [, eventData ], handler )
  • eventData — optional object passed to the handler as event.data.
  • handler — function called each time mouseover fires: function( event ) { ... }. Use event.relatedTarget to detect where the pointer came from.

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

jQuery
$( "#menu" ).on( "mouseover", "li", function( event ) {
  // runs when pointer enters any li inside #menu — bubbles from children
} );

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

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

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

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

Official jQuery API examples

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

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

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 mouseover handler$("#box").on("mouseover", fn)
Pair over and out (legacy).on("mouseover", show).on("mouseout", hide)
Filter child crossingsif ($(event.relatedTarget).closest("#outer").length) return;
Delegated mouseover on children$("#menu").on("mouseover", "li", fn)
Trigger mouseover programmatically$("#outer").trigger("mouseover")
Prefer for nested menus$("#nav").on("mouseenter", fn) instead of mouseover
Remove mouseover handlers$("#box").off("mouseover")

📋 mouseover vs mouseenter vs mouseout vs CSS :hover

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

mouseover
bubbles

Re-fires on every child boundary crossing — legacy hover pair with mouseout; filter with relatedTarget

mouseenter
enter once

Fires only when pointer enters bound element from outside — recommended for nested menus and tooltips

mouseout
bubbles

Exit counterpart to mouseover — pair for legacy hover; prefer mouseleave for nested content

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 event.relatedTarget filtering and the legacy mouseover + mouseout hover pair. Use the Try-it links to run each snippet in the browser.

📚 Binding & Triggering

Official jQuery demos for mouseover handlers and programmatic triggers.

Example 1 — Official Demo: Bind Handler on #outer

Append a log message when the pointer enters the outer element — the canonical .on("mouseover") pattern. Note: the handler also fires when moving into the Inner child (bubbles).

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

How It Works

.on("mouseover", fn) registers the function on #outer. jQuery calls it when the pointer crosses into the outer boundary and when moving from the outer area into the inner child — that bubbling behavior is the key difference from mouseenter.

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

One element programmatically fires the mouseover handler on another.

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

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

How It Works

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

Example 3 — Official Demo: mouseover vs mouseenter

Side-by-side comparison from the mouseover perspective — the left box re-fires on every child boundary crossing; the right box does not.

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

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

How It Works

The official API demo uses nested divs with an inner yellow child. mouseover on the left box bubbles — crossing into the inner div counts as a new entry event on the parent. mouseenter on the right ignores child crossings — the counter increments only when the pointer enters the entire outer box from outside. For nested menus, choose the right box pattern.

📈 Filtering & Legacy Hover Pairs

Practical patterns for taming mouseover bubbling and legacy over/out hover code.

Example 5 — Legacy Hover: mouseover + mouseout on Cards

Add highlight on over, remove on out — the classic pre-mouseenter hover pair. Works on flat cards; beware nested content inside each card.

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

How It Works

mouseover handles the show half; mouseout handles the hide half. On simple flat cards without nested children, this pair works fine. When cards contain buttons, icons, or nested spans, moving between those children triggers spurious out/over events — migrate to mouseenter + mouseleave for stable behavior.

🚀 Common Use Cases

  • Legacy hover pairs — maintain existing mouseover / mouseout code on flat elements without nested children.
  • Filter with relatedTarget — ignore child-boundary crossings when refactoring away from mouseover is not yet possible.
  • Highlight table rows$("tr").on("mouseover", fn) on table rows with no nested interactive elements.
  • Show flat tooltips — reveal a tooltip when entering a trigger that has no nested content inside it.
  • Event delegation$("#list").on("mouseover", "li", fn) when list items have no nested children.
  • Programmatic testing$("#box").trigger("mouseover") to verify show logic in unit tests.

🧠 How mouseover Bubbling Differs from mouseenter

1

Pointer outside outer box

User has not entered the bound element — no over event yet.

outside
2

Pointer enters outer box

mouseover and mouseenter both fire — handler runs for a true entry from outside.

true enter
3

Pointer moves to child

mouseover fires on the parent and bubbles up. mouseenter stays silent — still inside the outer boundary.

child cross
4

Stable hover

For nested menus and tooltips, use mouseenter + mouseleave — one enter, one leave, no duplicate firing from bubbling.

📝 Notes

  • Bind with .on("mouseover", handler) since jQuery 1.7 — not the deprecated .mouseover(handler) method.
  • Trigger with .trigger("mouseover") since jQuery 1.0.
  • mouseover bubbles — unlike mouseenter, it fires when moving from parent into a child.
  • Use event.relatedTarget to filter false positives when the pointer came from a child still inside the bound element.
  • For nested menus and tooltips, prefer mouseenter + mouseleave over mouseover + mouseout.
  • Any HTML element can receive mouseover — not limited to links or buttons.
  • Use .off("mouseover") to remove handlers — avoid deprecated .unbind("mouseover").
  • Touch devices have no true hover — provide click/tap fallbacks for critical UI.

Browser Support

The native mouseover event is supported in all browsers jQuery targets. jQuery’s .on("mouseover") (since 1.7) and .trigger("mouseover") (since 1.0) provide consistent collection binding, eventData, delegation, and programmatic triggering across browsers.

jQuery 1.7+

jQuery mouseover event

Supported in jQuery 1.x, 2.x, and 3.x across all modern browsers. Native equivalent: element.addEventListener('mouseover', fn) — universal support; jQuery 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
mouseover Universal

Bottom line: Safe in any jQuery project. Prefer .on('mouseover') over deprecated .mouseover() for binding. For nested content, use mouseenter or filter with event.relatedTarget.

Conclusion

The jQuery mouseover event fires when the pointer enters an element — and because it bubbles, it also fires when moving from a parent into a child inside the bound element. Bind handlers with .on("mouseover", fn), inspect event.relatedTarget to filter false positives, and fire handlers programmatically with .trigger("mouseover").

Choose mouseenter over mouseover when nested content would cause menus or tooltips to flicker from duplicate handler calls. Use the legacy mouseover + mouseout pair only on flat elements without nested children. Replace deprecated .mouseover(handler) with .on("mouseover", handler). For touch devices, remember hover has no mobile equivalent — add click fallbacks where needed.

💡 Best Practices

✅ Do

  • Bind with .on("mouseover", handler) — the modern, delegation-capable API
  • Prefer mouseenter + mouseleave for nested menus and tooltips
  • Filter child crossings with event.relatedTarget when stuck on mouseover
  • Use CSS :hover when only colors or visibility change
  • Call .off("mouseover mouseout") when removing legacy hover behavior

❌ Don’t

  • Use deprecated .mouseover(handler) for new code — use .on("mouseover")
  • Bind mouseover on containers with nested submenus without filtering
  • Assume one mouseover equals one true entry — bubbling fires on child crossings too
  • Rely on hover alone for critical mobile UI — add tap/click fallbacks
  • Forget to unbind over/out handlers when tearing down SPAs

Key Takeaways

Knowledge Unlocked

Six things to remember about the mouseover event

Bubbles, filter, prefer enter.

6
Core concepts
02

.trigger()

Fire

Programmatic
bubble 03

vs mouseenter

Bubbles

Compare
target 04

relatedTarget

Filter

Pattern
out 05

mouseout pair

Legacy

Hover
.off 06

.off("mouseover")

Unbind

Cleanup

❓ Frequently Asked Questions

The mouseover event fires when the mouse pointer enters an element. In modern jQuery, bind handlers with .on('mouseover', handler) since version 1.7. Unlike mouseenter, mouseover bubbles — it re-fires when the pointer moves from a parent into a child inside the bound element. Any HTML element can receive mouseover.
When the pointer enters a child element, mouseover bubbles up to ancestor elements bound with .on('mouseover'). A handler on the outer menu container fires even though the user has not truly entered the menu from outside — moving into a submenu looks like a fresh entry on the parent. That duplicate firing flickers hover styles and re-opens dropdowns. For nested menus, prefer mouseenter and mouseleave instead.
event.relatedTarget is the DOM element the pointer came from when mouseover fired. If relatedTarget is still inside the bound element (for example, a sibling child div), you can ignore the event: if ($(event.relatedTarget).closest('#outer').length) return;. This filters false positives caused by bubbling across child boundaries without switching to mouseenter.
mouseover bubbles and fires when entering the bound element OR when moving from the parent into a child inside it. mouseenter fires only when the pointer enters the bound element from outside — child crossings are ignored. For hover menus, tooltips, and containers with nested content, mouseenter (paired with mouseleave) avoids menus flickering when the user moves into a submenu.
Call .trigger('mouseover') on the target element: $('#outer').trigger('mouseover'). Available since jQuery 1.0, trigger runs bound mouseover handlers. To run handlers without bubbling, use .triggerHandler('mouseover') instead.
The deprecated .mouseover(handler) method binds a mouseover handler directly on the collection — it is shorthand for .on('mouseover', handler) in older jQuery. For new code, use .on('mouseover', fn) instead of .mouseover(fn). The event name is the same; only the binding API changed when .on() became the standard in jQuery 1.7.
Did you know?

The jQuery API documentation explicitly warns that mouseover “can cause many headaches due to event bubbling” and points developers to mouseenter as a useful alternative. When the pointer enters the inner child of a nested box, mouseover fires on the inner element first, then bubbles to the outer — triggering show logic at inopportune times. jQuery added proprietary mouseenter and mouseleave events (originally IE-only) specifically to solve this problem.

Next: .mouseover() Method

Learn the deprecated shorthand for binding and triggering mouseover — and how to migrate to .on("mouseover").

.mouseover() 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