jQuery mousemove Event

Beginner
8 min read
Updated: Oct 2026
5 examples
Live preview

What Is mousemove?

The mousemove event fires when the pointer moves inside an element (since jQuery 1.7 with .on()). Use it for drag UI, drawing, sliders, and live coordinates. jQuery normalizes event.pageX and event.pageY across browsers.

Remember
$("#box").on("mousemove", function (event) { … })

event.pageX / pageY   → document coordinates
event.clientX / clientY → viewport coordinates

.trigger("mousemove") → run handlers (coords may be undefined)
.off("mousemove")     → unbind when done
NeedUse
Bind handler$el.on("mousemove", fn)
Document coordsevent.pageX / event.pageY
Fire manually$el.trigger("mousemove")
Stop tracking$el.off("mousemove")

How to Use mousemove

Bind a light handler, read coordinates, and unbind when tracking is finished.

  1. Select the element that should report pointer movement.
  2. Bind with .on("mousemove", handler) (or only during drag — see below).
  3. Read event.pageX / event.pageY (or client coords) inside the handler.
  4. Unbind with .off("mousemove") as soon as you no longer need updates.
PieceRequired?Role
ElementYesReceives movement while pointer is inside
handlerYesfunction(event) { … }
eventDataOptionalObject passed as event.data
Return—jQuery object (chainable)

Pseudocode

Pseudocode
on mousemove inside element:
  x = event.pageX   // document X
  y = event.pageY   // document Y
  update UI lightly (or skip most frames)

// Official drag pattern (recommended):
on mousedown:
  bind mousemove on document
  on mouseup (document):
    unbind mousemove

Cheat Sheet

Keep these facts handy while tracking the pointer.

TopicDetail
Bind.on("mousemove", handler) (1.7+)
Trigger.trigger("mousemove") (1.0+)
pageX / pageYDocument origin — normalized by jQuery
clientX / clientYViewport origin
FrequencyCan fire hundreds of times per second
vs mouseenterenter once; mousemove = continuous
Shorthand.mousemove() deprecated — use .on()

Live Preview

Move the pointer over the track pad to see pageX / pageY vs clientX / clientY.

Browser demo of mousemove — same idea as the examples below.

Result
Move the pointer over the track pad
→ pageX / pageY and clientX / clientY update live

jQuery Examples

Short, copy-ready snippets. Open each Try It Yourself lab for a live editor.

Example 1 — Log pageX / pageY

Append coordinates each time the pointer moves over the target — the official .on("mousemove") pattern.

jQuery
$("#target").on("mousemove", function (event) {
  var msg = "Handler for mousemove called at ";
  msg += event.pageX + ", " + event.pageY;
  $("#log").append(msg + "\n");
});
Try It Yourself

How It Works

  1. Bind the event. .on("mousemove", fn) registers the handler on #target.
  2. Move inside the element. Each pixel of movement calls the function.
  3. Read document coords. jQuery provides normalized pageX and pageY.
  4. Update the log. Append a short message — keep the work minimal.

Example 2 — Trigger from Another Element

Click a button to fire the same handler with .trigger("mousemove") — coordinates are often undefined.

jQuery
$("#target").on("mousemove", function (event) {
  $("#log").append(
    "at " + event.pageX + ", " + event.pageY + "\n"
  );
});

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

How It Works

  1. Same handler. Real moves and triggers both call the bound function.
  2. Synthetic event. .trigger("mousemove") has no real pointer.
  3. Missing coords. pageX / pageY are often undefined.
  4. Custom values. Pass a custom event object if your handler needs specific coordinates.

Example 3 — pageX vs clientX

Show both coordinate systems while moving — adapted from the official jQuery API demo.

jQuery
$("#pad").on("mousemove", function (event) {
  $("#page").text(
    "page: (" + event.pageX + ", " + event.pageY + ")"
  );
  $("#client").text(
    "client: (" + event.clientX + ", " + event.clientY + ")"
  );
});
Try It Yourself

How It Works

  1. Document coords. pageX / pageY include scroll offset.
  2. Viewport coords. clientX / clientY are relative to the visible window.
  3. jQuery helps. pageX / pageY are normalized for consistent cross-browser use.
  4. Pick by goal. Page layout → page; fixed UI overlays → client.

Example 4 — Drag Bind / Unbind Pattern

Bind mousemove only while the button is pressed — the official performance pattern.

jQuery
function onMove(event) {
  $("#box").css({ left: event.pageX - 25, top: event.pageY - 25 });
}

$("#box").on("mousedown", function (event) {
  if (event.which !== 1) return;
  $(document).on("mousemove", onMove);
  $(document).one("mouseup", function () {
    $(document).off("mousemove", onMove);
  });
});
Try It Yourself

How It Works

  1. Start on press. mousedown begins the drag and attaches mousemove to document.
  2. Track globally. Document-level move keeps following even outside the box.
  3. Stop on release. .one("mouseup") unbinds move — works even if release is outside.
  4. Named handler. Passing onMove to .off() removes only that listener.

Example 5 — Local Coordinates Inside a Zone

Convert document coordinates to positions relative to the element with .offset().

jQuery
var $zone = $("#zone");

$zone.on("mousemove", function (event) {
  var offset = $zone.offset();
  var x = event.pageX - offset.left;
  var y = event.pageY - offset.top;
  $("#readout").text("Local: " + Math.round(x) + ", " + Math.round(y));
});

$zone.on("mouseleave", function () {
  $("#readout").text("Move inside the zone");
});
Try It Yourself

How It Works

  1. Get zone origin. .offset() returns the element’s document position.
  2. Subtract. pageX - left and pageY - top give local X/Y.
  3. Show the readout. Round values for a clean display.
  4. Reset on leave. Pair with mouseleave when the pointer exits.

Edge Cases & Pitfalls

Check these before shipping pointer-tracking UI.

perf

Handlers fire constantly

Hundreds of calls per second. Avoid heavy DOM work, animations, or AJAX inside every move.

unbind

Leave listeners hanging

A permanent document mousemove wastes CPU. Unbind on mouseup (or when the feature ends).

trigger

Triggered coords may be undefined

.trigger("mousemove") is not a real pointer event. Guard or pass coordinates when needed.

mouseup

Release outside the element

Bind mouseup on document so drag cleanup still runs when the user releases elsewhere.

touch

Not a touch event

mousemove is mouse-oriented. For fingers, look at touch / pointer events separately.

Browser Support

The mousemove event is a standard DOM mouse event. jQuery’s .on("mousemove") (since 1.7) and normalized pageX/pageY work in any browser where your jQuery build runs.

✓ jQuery 1.7+ · Browsers

jQuery mousemove event

Supported wherever jQuery runs — Chrome, Firefox, Safari, Edge, and legacy environments with a matching jQuery build.

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
mousemove Browsers

Bottom line: Safe in all common browsers with jQuery loaded. Prefer .on() / .off() over the deprecated .mousemove() shorthand.

Performance Notes

ApproachCostBest for
Always-on mousemoveVery high frequencySmall readouts only
Bind during drag onlyActive while pressedDrag, draw, resize
Throttle / rAF~1 update per frameSmooth visual tracking

Official guidance: optimize handlers and unbind when finished. Prefer the mousedown → mousemove → mouseup sequence for drag UI instead of a permanent document listener.

Key Takeaways

  • Role: continuous pointer tracking inside an element.
  • Coords: prefer pageX / pageY for document-relative position.
  • API: use .on("mousemove"), not the deprecated .mousemove() shorthand.
  • Drag: bind on mousedown, unbind on document mouseup.

One line: mousemove follows the pointer — keep the handler light and unbind when you are done.

Frequently Asked Questions

mousemove fires whenever the mouse pointer moves inside an element — even by one pixel. Bind with .on('mousemove', handler) (since jQuery 1.7). Any HTML element can receive it. It is one of the highest-frequency browser events, so keep handlers light.
pageX and pageY are relative to the document (including scroll). clientX and clientY are relative to the viewport. jQuery normalizes pageX and pageY across browsers — prefer them when positioning elements on the page.
It can fire hundreds of times per second. Heavy DOM work, layout thrashing, or multiple handlers per move can slow the page. Keep handlers fast, throttle or use requestAnimationFrame when needed, and unbind as soon as tracking is done.
Bind mousemove inside a mousedown handler, then unbind on mouseup. Attach mouseup high in the DOM (often $(document).one('mouseup', fn)) because release may happen outside the original element.
Call .trigger('mousemove') on the element. Handlers run, but pageX and pageY are often undefined unless you pass a custom event object with coordinates.
Use .on('mousemove', handler). The .mousemove() shorthand is deprecated since jQuery 3.3. Unbind with .off('mousemove'). .on() also supports delegation: .on('mousemove', '.handle', fn).

Next: .mousemove()

See the deprecated shorthand and how it maps to .on("mousemove").

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

10 people found this page helpful