Is it possible to get the mouse position with JavaScript after page loads without any mouse movement event (without moving the mouse)?
-
71Nothing wrong with the mousemove event. Just in some cases users don't move the mouse. Thanks for your answer. – Norbert Tamas Apr 08 '10 at 15:28
-
2Norbert Tamas, @SuperNova's answer (which wasn't added until this year) shows that mouseenter works fine for this because it fires on page load (if the mouse is in the viewport). Did it not work that way in 2010, or is it just that no one thought to try it? – Peter Hansen Nov 23 '14 at 02:12
-
2@CrescentFresh In some cases (like userscripts) you don't want to slow down the browser by adding many `mousemove` events. – Tomáš Zato Nov 29 '14 at 14:23
-
Possible in FF with mouseover, but isn't in IE and Chrome. – Elad May 27 '15 at 10:39
-
Or, in a game, your camera moves around the game world and the character is looking at the mouse (typical top-down shooter style) but if user doesn't move a mouse, it centers around the wrong point as you move around if you rely only on mousemove. However, it's not a big deal, we just store the "world" coords of the pointer and let people query that. – kamranicus Aug 22 '15 at 14:47
-
To improve performance of this solution * Create an element with 1px height and 100% width and add :hover pseudo-class * Scan from the top of the document one pixel at a time to find Y position * After getting Y coordinate do the scan on the X axis (this time the element can be only 1px x 1px) – Pawel Sep 22 '15 at 14:23
-
@Pawel Are you saying that, as you move the element, as soon as it is underneath the mouse that it can trigger an event? In the following jsfiddle, leave the mouse under the black bar and wait for the black bar to go underneath without moving, and see the mouseover and mouseenter events are not firing. https://jsfiddle.net/bowp569a/. – trusktr Feb 17 '20 at 23:54
-
@Pawel Here's the same effort using the `:hover` pseudo selector, but it doesn't work without actually moving the mouse: https://jsfiddle.net/z9w20f53/ – trusktr Feb 17 '20 at 23:56
15 Answers
Real answer: No, it's not possible.
OK, I have just thought of a way. Overlay your page with a div that covers the whole document. Inside that, create (say) 2,000 x 2,000 <a>
elements (so that the :hover
pseudo-class will work in IE 6, see), each 1 pixel in size. Create a CSS :hover
rule for those <a>
elements that changes a property (let's say font-family
). In your load handler, cycle through each of the 4 million <a>
elements, checking currentStyle
/ getComputedStyle()
until you find the one with the hover font. Extrapolate back from this element to get the co-ordinates within the document.
N.B. DON'T DO THIS.

- 318,141
- 75
- 454
- 536
-
124ha ha - at some point you should google around and see if you can figure out how many people have actually implemented this – Pointy Apr 08 '10 at 15:46
-
6Actually, it is implementable without having to much CPU load (I think. I haven't been testing it). On dom ready build the elements with javascript, take the mouse postion and then remove all elements. On mousemouse you should have other function to take the mouse position. Anyway, this was hilarious. – machineaddict Aug 16 '12 at 05:40
-
25Perhaps this could be made practical with binary search? Loop making a pair of `` elements covering given rectangles (using absolute positioning of sized `
` elements, I suppose), shrinking the rectangles each time. Yes, it's ridiculous, but so is not being able to get this info before the first mousemove. – Darius Bacon May 28 '13 at 22:24
-
34http://stackoverflow.com/a/8543879/27024 says the hover doesn't fire either until the mouse moves for the first time. This foils this scheme. – Darius Bacon May 28 '13 at 22:28
-
4@DariusBacon: That linked answer doesn't seem to be correct: http://jsbin.com/utocax/3. So yes, this approach may be practical for some situations. – Tim Down May 29 '13 at 09:18
-
3@TimDown a small part of me hoped to see 4 mil elements while the jsbin example page was loading :D – Jaak Kütt Apr 19 '14 at 07:58
-
2You could implement this much more efficiently by using divide-and-conquer, e.g. a binary search. You only need two elements then. – Mark K Cowan Sep 10 '14 at 17:42
-
2I think that I can just wait until the mouse moves once and not set the CPU on fire. – trinalbadger587 Jun 23 '15 at 08:18
-
4Although this funny solution sounds like something that is ridiculous but working, it's not actually a working solution. It has the same problem which was there in the first place: hover events do not occur when the mouse doesn't move. You can cover your page in "hoverable" elements all you want, and they still won't be hovered upon page refresh until the mouse moves. But then you could simply respond to the mousemove event. – timetowonder Jan 28 '16 at 22:53
-
2@timetowonder: I'm not sure that's always been entirely true in all browsers and operating systems. I'm pretty sure I had a simple example working in at least one browser at one time. – Tim Down Jan 29 '16 at 09:22
-
1I don't see why this gets upvoted at all, when there's a real answer in this same topic. – polkovnikov.ph Feb 09 '16 at 19:20
-
2@polkovnikov.ph When I wrote this, there wasn't a real answer and if the "real answer" works then browser behaviour has changed since then. However, I do agree that this shouldn't be the accepted answer. – Tim Down Feb 10 '16 at 15:42
-
This is kind of amazing as it's a clear edge case for SOF. On one hand you have a clearly thoughtful answer that feasibly worked at the time of writing, which [outdated answers] are part of the nature of the historical data in general. On the other hand this "solution" is a total hack while fully encompassing the purest spirit of ingenuity and ingenuity is core to SOF! I want to see answers like this stay and I second (or third at this point) that this needn't be the accepted answer. – Jacksonkr Jan 31 '19 at 18:42
-
@Pointy maybe _you_ should share one of those links for people who did google around and found this question at the top of their search results – gillonba Jan 30 '21 at 00:58
-
@gillonba this is essentially an impractical joke answer to the question, and it's from 11 years ago. – Pointy Jan 30 '21 at 12:18
Edit 2020: This does not work any more. It seems so, that the browser vendors patched this out. Because the most browsers rely on chromium, it might be in its core.
Old answer: You can also hook mouseenter (this event is fired after page reload, when the mousecursor is inside the page). Extending Corrupted's code should do the trick:
var x = null;
var y = null;
document.addEventListener('mousemove', onMouseUpdate, false);
document.addEventListener('mouseenter', onMouseUpdate, false);
function onMouseUpdate(e) {
x = e.pageX;
y = e.pageY;
console.log(x, y);
}
function getMouseX() {
return x;
}
function getMouseY() {
return y;
}
You can also set x and y to null on mouseleave-event. So you can check if the user is on your page with it's cursor.

- 2,792
- 2
- 25
- 34
-
12This would seem to be the only truly useful answer here, which seems odd. Indeed (in latest Firefox, Chrome and IE11) the mouseenter fires on page load and provides the correct coordinates. Has browser behaviour in this area simply changed in the last few years? – Peter Hansen Nov 23 '14 at 02:10
-
3In fact "mouseenter" doesn't seem to add any value. I tested with the following jsfiddle in Chrome and IE, and they don't show the cordinates until you put the mouse on the inner document (the result panel): http://jsfiddle.net/xkpd784o/1/ – Mariano Desanze May 14 '15 at 00:54
-
1@Proton: Move your mouse to the result panel to the area of the resultpanel BEFORE page has fully loaded and don't move than. After onload the page immediatly knows the position of the mouse. No mouse movement is needed. So mouseenter is also fired, when the page has loaded and the mouse is inside the document area. That is, what the OP originally wanted. No one other provides this answer. – SuperNova May 15 '15 at 06:31
-
1A potentially useful addition is to add a function for the `mouseleave` event that sets `x` and `y` back to `null` or `'undefined'` – rtpax Dec 13 '16 at 23:02
-
1@brillout.com I've just tested it in Chrome 57 under windows: Works like a charm. What did not work in your test? – SuperNova Apr 24 '17 at 08:38
-
2chrome 68, using the jsfiddel above, alert occurs on first mouse move and not on load, even if mouse is moved to the rendered region before the page finished loading. – junvar Aug 04 '18 at 20:16
-
It seems to be a problem with the fiddle (now) or the used iframes on jsfiddle. Putting the code into a blank html file running local or via http is working like a charm for me (chrome 68) – SuperNova Aug 06 '18 at 14:26
-
1**Doesn't work.** I just tested on a blank page in Chrome, Firefox and Edge. Neither `mouseenter` nor `mousemove` fire on page load even if the cursor is inside the page. See my answer for a better solution: https://stackoverflow.com/a/52141050/362006 – Samuel Katz Sep 02 '18 at 21:25
-
As above, I've done various tests in Firefox and Chrome and this doesn't work on refresh, although it does work in Chrome after refresh on mouse move, but that's not what we want. – Paul Feakins Jan 14 '20 at 11:14
-
The browser vendors seem to have this patched out. My answer is from 2014 and it worked several years. – SuperNova Jan 20 '20 at 06:38
What you can do is create variables for the x
and y
coordinates of your cursor, update them whenever the mouse moves and call a function on an interval to do what you need with the stored position.
The downside to this of course is that at least one initial movement of the mouse is required to have it work. As long as the cursor updates its position at least once, we are able to find its position regardless of whether it moves again.
var cursor_x = -1;
var cursor_y = -1;
document.onmousemove = function(event)
{
cursor_x = event.pageX;
cursor_y = event.pageY;
}
setInterval(check_cursor, 1000);
function check_cursor(){console.log('Cursor at: '+cursor_x+', '+cursor_y);}
The preceding code updates once a second with a message of where your cursor is.
-
31Did you read the subject of this post? The OP asks how to get the mouse coordinates without using an event. Yet your post suggests using the onmousemove event. – jake Dec 18 '12 at 00:36
-
67@jake Although the OP specifically asked for a non-event method, this answer benefits others who came here looking for an answer and possibly a workaround. Also, I'd consider this answer partially within topic since as far as I know, this is the best method to get the cursor position at any given time without having to use events directly. That said, the answer could've been worded more along the lines of stating the fact and offering a way around to avoid nitpicking in comments. – jpeltoniemi Apr 01 '13 at 00:50
-
3@Pichan It didn't benefit me, because I've been looking for a way to fill those `cursorX/Y` variable before any event happens. – polkovnikov.ph Feb 09 '16 at 17:11
-
-
1Careful, it can be costly to keep an mousemove listener around. I would suggest recreating the listener in the interval and destroying the listener after you get coordinates. – KRB Mar 01 '17 at 18:50
-
1
@Tim Down's answer is not performant if you render 2,000 x 2,000 <a>
elements:
OK, I have just thought of a way. Overlay your page with a div that covers the whole document. Inside that, create (say) 2,000 x 2,000 elements (so that the :hover pseudo-class will work in IE 6, see), each 1 pixel in size. Create a CSS :hover rule for those elements that changes a property (let's say font-family). In your load handler, cycle through each of the 4 million elements, checking currentStyle / getComputedStyle() until you find the one with the hover font. Extrapolate back from this element to get the co-ordinates within the document.
N.B. DON'T DO THIS.
But you don't have to render 4 million elements at once, instead use binary search. Just use 4 <a>
elements instead:
- Step 1: Consider the whole screen as the starting search area
- Step 2: Split the search area into 2 x 2 = 4 rectangle
<a>
elements - Step 3: Using the
getComputedStyle()
function determine in which rectangle mouse hovers - Step 4: Reduce the search area to that rectangle and repeat from step 2.
This way you would need to repeat these steps max 11 times, considering your screen is not wider than 2048px.
So you will generate max 11 x 4 = 44 <a>
elements.
If you don't need to determine the mouse position exactly to a pixel, but say 10px precision is OK. You would repeat the steps at most 8 times, so you would need to draw max 8 x 4 = 32 <a>
elements.
Also generating and then destroying the <a>
elements is not performat as DOM is generally slow. Instead, you can just reuse the initial 4 <a>
elements and just adjust their top
, left
, width
and height
as you loop through steps.
Now, creating 4 <a>
is an overkill as well. Instead, you can reuse the same one <a>
element for when testing for getComputedStyle()
in each rectangle. So, instead of splitting the search area into 2 x 2 <a>
elements just reuse a single <a>
element by moving it with top
and left
style properties.
So, all you need is a single <a>
element change its width
and height
max 11 times, and change its top
and left
max 44 times and you will have the exact mouse position.

- 361
- 2
- 12
-
Clever! This is the only answer to actually "answer" the question in a performant way. Has anyone come up with a proof of concept fiddle? – Hans Brende Aug 24 '22 at 19:02
You could try something similar to what Tim Down suggested - but instead of having elements for each pixel on the screen, create just 2-4 elements (boxes), and change their location, width, height dynamically to divide the yet possible locations on screen by 2-4 recursively, thus finding the mouse real location quickly.
For example - first elements take right and left half of screen, afterwards the upper and lower half. By now we already know in which quarter of screen the mouse is located, are able to repeat - discover which quarter of this space...
Here's my solution. It exports window.currentMouseX and window.currentMouseY properties you can use anywhere. It uses the position of a hovered element (if any) initially and afterwards listens to mouse movements to set the correct values.
(function () {
window.currentMouseX = 0;
window.currentMouseY = 0;
// Guess the initial mouse position approximately if possible:
var hoveredElement = document.querySelectorAll(':hover');
hoveredElement = hoveredElement[hoveredElement.length - 1]; // Get the most specific hovered element
if (hoveredElement != null) {
var rect = hoveredElement.getBoundingClientRect();
// Set the values from hovered element's position
window.currentMouseX = window.scrollX + rect.x;
window.currentMouseY = window.scrollY + rect.y;
}
// Listen for mouse movements to set the correct values
window.addEventListener('mousemove', function (e) {
window.currentMouseX = e.pageX;
window.currentMouseY = e.pageY;
}, /*useCapture=*/true);
}())
Composr CMS Source: https://github.com/ocproducts/composr/commit/a851c19f925be20bc16bfe016be42924989f262e#diff-b162dc9c35a97618a96748639ff41251R1202

- 24,066
- 8
- 71
- 57
The most simple solution but not 100% accurate
$(':hover').last().offset()
Result: {top: 148, left: 62.5}
The result depend on the nearest element size and return undefined
when user switched the tab

- 2,802
- 3
- 24
- 25
-
For me, it returns `undefined` regardless. Can you elaborate as how to use this? – tresf Mar 08 '18 at 16:06
-
It would return `undefined` when the cursor wasn't hovering any element (or when the browser lost focus). You may need to set a time interval if you're testing from the console.. – StefansArya Mar 10 '18 at 04:12
-
Thanks. `setTimeout` worked. I was using jsfiddle and you're right, it never hit a hover event because it redraws the DOM each time you click play. I would recommend adding this hint for others. – tresf Mar 10 '18 at 08:03
-
I do not want accurate mouse position but i just want to know that mouse is extreme right or extreme left into function without event object so your solution works in my case..thank you – Swap-IOS-Android Oct 30 '18 at 13:41
Yes, It's possible.
If you add "mouseover" event to the document it will fire instantly and you can get the mouse position, of course if mouse pointer was over the document.
document.addEventListener('mouseover', setInitialMousePos, false);
function setInitialMousePos( event ) {
console.log( event.clientX, event.clientY);
document.removeEventListener('mouseover', setInitialMousePos, false);
}
Previously it was possible to read mouse position through window.event
but it's deprecated now.

- 641
- 8
- 13
var x = 0;
var y = 0;
document.addEventListener('mousemove', onMouseMove, false)
function onMouseMove(e){
x = e.clientX;
y = e.clientY;
}
function getMouseX() {
return x;
}
function getMouseY() {
return y;
}

- 83
- 1
-
14
-
Yes but only the first move. Then when its moved once we know already the px X Y – mmonteirocl Nov 05 '20 at 07:56
I implemented a horizontal/vertical search, (first make a div full of vertical line links arranged horizontally, then make a div full of horizontal line links arranged vertically, and simply see which one has the hover state) like Tim Down's idea above, and it works pretty fast. Sadly, does not work on Chrome 32 on KDE.
jsfiddle.net/5XzeE/4/

- 11
- 2
-
apparently these tricks no longer work unless there is an explicit mouse move by the user. :( – trusktr Feb 18 '20 at 00:03
You do not have to move the mouse to get the cursor's location. The location is also reported on events other than mousemove. Here's a click-event as an example:
document.body.addEventListener('click',function(e)
{
console.log("cursor-location: " + e.clientX + ',' + e.clientY);
});

- 9,936
- 10
- 57
- 97
Riffing on @SuperNova's answer, here's an approach using ES6 classes that keeps the context for this
correct in your callback:
class Mouse {
constructor() {
this.x = 0;
this.y = 0;
this.callbacks = {
mouseenter: [],
mousemove: [],
};
}
get xPos() {
return this.x;
}
get yPos() {
return this.y;
}
get position() {
return `${this.x},${this.y}`;
}
addListener(type, callback) {
document.addEventListener(type, this); // Pass `this` as the second arg to keep the context correct
this.callbacks[type].push(callback);
}
// `handleEvent` is part of the browser's `EventListener` API.
// https://developer.mozilla.org/en-US/docs/Web/API/EventListener/handleEvent
handleEvent(event) {
const isMousemove = event.type === 'mousemove';
const isMouseenter = event.type === 'mouseenter';
if (isMousemove || isMouseenter) {
this.x = event.pageX;
this.y = event.pageY;
}
this.callbacks[event.type].forEach((callback) => {
callback();
});
}
}
const mouse = new Mouse();
mouse.addListener('mouseenter', () => console.log('mouseenter', mouse.position));
mouse.addListener('mousemove', () => console.log('mousemove A', mouse.position));
mouse.addListener('mousemove', () => console.log('mousemove B', mouse.position));

- 2,206
- 21
- 26
Not mouse position, but, if you're looking for current cursor postion (for use cases like getting last typed character etc) then, below snippet works fine.
This will give you the cursor index related to text content.
window.getSelection().getRangeAt(0).startOffset

- 42,508
- 29
- 229
- 225
I envision that maybe you have a parent page with a timer and after a certain amount of time or a task is completed, you forward the user to a new page. Now you want the cursor position, and because they are waiting, they aren't necessarily touching the mouse. So track the mouse on the parent page using standard events and pass the last value to the new page in a get or a post variable.
You can use JHarding's code on your parent page so that the latest position is always available in a global variable:
var cursorX;
var cursorY;
document.onmousemove = function(e){
cursorX = e.pageX;
cursorY = e.pageY;
}
This won't help users that navigate to this page by means other than your parent page.
I think i may have a reasonable solution with out counting divs and pixels..lol
Simply use animation frame or a time interval of a function. you will still need a mouse event one time though just to initiate, but technically you position this where ever you like.
Essentially we are tracking a dummy div at all times with out mouse movement.
// create a div(#mydiv) 1px by 1px set opacity to 0 & position:absolute;
Below is the logic..
var x,y;
$('body').mousemove(function( e ) {
var x = e.clientX - (window.innerWidth / 2);
var y = e.clientY - (window.innerHeight / 2);
}
function looping (){
/* track my div position 60 x 60 seconds!
with out the mouse after initiation you can still track the dummy div.x & y
mouse doesn't need to move.*/
$('#mydiv').x = x; // css transform x and y to follow
$('#mydiv)'.y = y;
console.log(#mydiv.x etc)
requestAnimationFrame( looping , frame speed here);
}

- 676
- 1
- 5
- 19