Get the mouse cursor position in JavaScript and jQuery
There is no global "where is the mouse" property in the browser: the position comes with each mouse or pointer event. The event carries several pairs of coordinates, each relative to something different, and picking the right pair is the whole difficulty.
The coordinate pairs
| Properties | Relative to |
|---|---|
clientX, clientY | The viewport (visible area); unaffected by scrolling |
pageX, pageY | The whole document, including the scrolled-away part |
screenX, screenY | The physical screen |
offsetX, offsetY | The padding edge of the event's target element |
Live display
<p id="pos">Move the mouse</p>
<script>
document.addEventListener("mousemove", function (e) {
document.getElementById("pos").textContent =
"client " + e.clientX + "," + e.clientY + " · page " + e.pageX + "," + e.pageY;
});
</script>
jQuery normalises the same properties on its event object: $(document).on("mousemove", function (e) { … e.pageX … }).
Position inside an element
offsetX refers to whatever element is under the pointer, which may be a child. For coordinates relative to a specific container, compute them:
var box = document.getElementById("canvasArea");
box.addEventListener("mousemove", function (e) {
var r = box.getBoundingClientRect();
var x = Math.round(e.clientX - r.left);
var y = Math.round(e.clientY - r.top);
box.title = x + ", " + y;
});
Touch and pen: pointer events
Mouse events are emulated on touch screens, but not for continuous movement. Pointer events cover mouse, touch and pen with one API and the same coordinate properties:
box.addEventListener("pointermove", function (e) {
// e.pointerType is "mouse", "touch" or "pen"
});
Add the CSS touch-action: none on the element if touch movement should not scroll the page while you track it.
A tooltip that follows the cursor
<style>
#follow { position: fixed; pointer-events: none; padding: .2rem .4rem;
background: #222; color: #fff; font-size: .8rem; border-radius: 4px; display: none; }
</style>
<div id="follow"></div>
<script>
var tip = document.getElementById("follow");
document.querySelectorAll("[data-tip]").forEach(function (el) {
el.addEventListener("mouseenter", function () { tip.textContent = el.dataset.tip; tip.style.display = "block"; });
el.addEventListener("mouseleave", function () { tip.style.display = "none"; });
el.addEventListener("mousemove", function (e) {
tip.style.left = (e.clientX + 12) + "px"; // position: fixed uses viewport coordinates
tip.style.top = (e.clientY + 12) + "px";
});
});
</script>
Because the tooltip is position: fixed, it uses clientX/clientY; an absolutely positioned element in the document would use pageX/pageY. Mouse-only hints are invisible to keyboard and touch users, so keep essential information elsewhere; a focusable alternative is the CSS3 tooltip.
Official documentation
- MDN: MouseEvent (clientX, pageX, screenX, offsetX), Pointer events, getBoundingClientRect()
- jQuery API: Event object