jQuery Mouse Events: PageX/Y vs. ClientX/Y

Posted March 8, 2010 at 9:19 AM by Ben Nadel

Tags: Javascript / DHTML

When I first starting playing with jQuery events, a lot of what I learned about the jQuery Event object was through trial and error. While I could be remembering incorrectly, I used to find that the jQuery documentation was good at describing the event handlers, but not so good at describing the event object; as such, while I knew that the jQuery event object was a standardized event object, I was never 100% sure which parts of it I was supposed to be using.

 
 
 
 
 
 
 
 
 
 

Through my trial and error, I started to use the clientX and clientY mouse coordinates in the jQuery event object. These coordinates gave me the X and Y offset of the mouse relative to the top-left corner of the browser's view port. As I was reading the jQuery 1.4 Reference Guide by Karl Swedberg and Jonathan Chaffer, however, I saw that they often referred to the pageX and pageY coordinates. After checking the updated jQuery documentation, I saw that these were the coordinates standardized by jQuery; and, I saw that they gave me the X and Y offset of the mouse relative to the entire document (not just the view port).

To see the difference between these two coordinate systems, I set up a page that would log mouse click events against a visible coordinate grid.

  • <!DOCTYPE HTML>
  • <html>
  • <head>
  • <title>jQuery Mouse Events: ClientX vs. PageX</title>
  • <style type="text/css">
  •  
  • div.grid {
  • border: 1px solid #CCCCCC ;
  • cursor: pointer ;
  • font: 10px verdana ;
  • height: 99px ;
  • position: absolute ;
  • width: 99px ;
  • z-index: 100 ;
  • }
  •  
  • </style>
  • <script type="text/javascript" src="jquery-1.4.2.js"></script>
  • <script type="text/javascript">
  •  
  • // I draw the grid on the document.
  • function createGrid(){
  • var body = $( "body" );
  •  
  • // Draw the X axis.
  • for (var x = 0 ; x <= 2000 ; x += 100){
  •  
  • // Draw the Y axis.
  • for (var y = 0 ; y <= 2000 ; y += 100){
  •  
  • $( "<div class='grid'></div>" )
  • .appendTo( body )
  • .css({
  • left: (x + "px"),
  • top: (y + "px")
  • })
  • .text( x + "," + y )
  • ;
  •  
  • }
  •  
  • }
  • };
  •  
  •  
  • // When the DOM is ready, initialize the scripts.
  • jQuery(function( $ ){
  •  
  • // Create the grid for coordinate affordance.
  • createGrid();
  •  
  • // Bind the mouse event to the document so that we
  • // can see what kind of coordinates we have to play
  • // with.
  • $( document ).click(
  • function( event ){
  •  
  • // Client variables.
  • console.log(
  • "clientX/Y: " +
  • event.clientX + ", " +
  • event.clientY
  • );
  •  
  • // Page variables. NOTE: These are the ones
  • // that are officially supported by the
  • // jQuery Event object.
  • console.log(
  • "pageX/Y: " +
  • event.pageX + ", " +
  • event.pageY
  • );
  •  
  • // Hrule.
  • console.log( "......" );
  •  
  • }
  • );
  •  
  • });
  •  
  • </script>
  • </head>
  • <body>
  • <!-- Nothing needed here. -->
  • </body>
  • </html>

As you can see, I create a 2000 x 2000 pixel grid that will give me both horizontal and vertical scrolling. And, when I scroll both right and down, and then click on the document, I get the following console output:

 
 
 
 
 
 
jQuery Event Object Uses PageX And PageY As The Standardized Mouse Event Coordinates. 
 
 
 

As you can see, the clientX and clientY coordinates give me the mouse position relative to the view port, regardless of the scroll of the document. The pageX and pageY coordinates, on the other hand, give me the mouse position relative to the top, left of the entire document, again regardless of the scrolling.

Which mouse event coordinates you should be using is not really a question for debate - the pageX and pageY coordinates are the ones that have been standardized by jQuery. In order to keep your code as cross-browser compatible as possible, you should rely on pageX and pageY. It is unfortunate that I did not know about this until just recently - I am quite sure that I have posted a lot of code that accidentally relied on the proprietary event properties, clientX and clientY.




Reader Comments

Mar 8, 2010 at 11:58 AM // reply »
1 Comments

Thanks a lot for this post! Good that you took notice of it : this will be helpful for my map browser.


Mar 8, 2010 at 12:09 PM // reply »
11,246 Comments

@Philippe,

The standardization of the jQuery event object is nice... especially when you finally know what the standard actually is ;)


Mar 8, 2010 at 7:13 PM // reply »
1 Comments

I've been trying to find a way to determine the X/Y mouse coordinates in relation to a given element. That way I could tell if my mouse is the left 50% of a given <div>, or the top 33% of a given image and show/hide things appropriately.

Is there a way to extrapolate the pageX/Y into coords related to a certain element.


Mar 8, 2010 at 7:29 PM // reply »
11,246 Comments

@Scott,

For something like that, I would use the offset() of the given element in conjunction with the pageX/pageY.

I use this approach a lot, but have not pointed it out specifically. I'll write up a quick post and paste a link here.


Mar 9, 2010 at 9:38 AM // reply »
11,246 Comments

@Scott,

Take a look at this exploration:

http://www.bennadel.com/blog/1871-Translating-Global-jQuery-Event-Coordinates-To-A-Local-Context.htm


Mar 9, 2010 at 1:00 PM // reply »
1 Comments

Very good article. Opened up my mind to many cool possibilities.

Thanks, I want to try this on the map.


Mar 10, 2010 at 10:07 PM // reply »
11,246 Comments

@Peter,

Glad you like it. Drop another comment if you come up with some cool ways to use this.


Rex
Mar 30, 2010 at 10:47 PM // reply »
1 Comments

thanks a lot,


Apr 29, 2010 at 9:13 AM // reply »
1 Comments

Very useful. I've been using pageX/pageY as this is what I learnt initially, so I guess thats a bonus!

On the other hand, I do see some benefits of having both values, as it can often be useful to know *where* in the page the visitors browser is viewing. I wouldn't necessarily ignore clientX/clientY usage because, for the right task, namely some fancy jQuery-based animation, this is exactly what is needed.

Am I wrong to suggest this?
I think advanced jQuery visuals on sites would probably rely on a mixture of client/page/X/Y along with offset() and many other jQuery blessings.


May 16, 2010 at 10:43 PM // reply »
11,246 Comments

@Rhys,

I think both sets of values definitely have their place. The big question is - can you rely on the clientX/clientY to always be there? The beauty of the jQuery library is that it standardizes what is available in the event object; according to the docs, they promise to supply the pageX/pageY, not the clientX/clientY. So, while I have used it without problem, I am not sure that means that it will always hold the values you expect.


May 27, 2010 at 3:34 AM // reply »
1 Comments

The Compatibility information listed at http://www.quirksmode.org/dom/w3c_cssom.html
infact shows clientX,clientY to be the one consistent on most browsers. So it should be safe using clientX,clientY right ?


Jun 7, 2010 at 10:56 PM // reply »
11,246 Comments

@Jitendra,

I am not sure how to best answer that. Even if it is most consistent, we are using a library that standardizes on a given set of properties. I think , if we use the library (jQuery), then we need to depend more on what they standardize on. But, as I said in the blog post, I was using the wrong ones for a while without any problem... so it appears to be quite safe by coincidence.


Nov 5, 2010 at 10:19 PM // reply »
2 Comments

hi, thank you for the good article.

if I have <div style="height:600px;width:800px;overflow:auto;"> with 2 scollbars. How to determine mouse position. if I scroll down/right, the pageX/pageY show same numbers.


Nov 5, 2010 at 11:57 PM // reply »
2 Comments

@rick,

after google search, scrollTop() is what I want. :-)


DA
Aug 18, 2011 at 2:45 PM // reply »
1 Comments

I've been a bit confused about this. Every bit of documentation I can find seems to say to use pageX/pageY. However, that always returns 0 for me in my jQuery on an iPhone. After some digging, I came across this page:

https://github.com/jquery/jquery-mobile/issues/734

which has some sample code with this comment in it:

// (in iOS event.pageX and event.pageY are always 0 )

which seems to back up my conclusion. I don't know if this is a failing of mobile safari or of jQuery, but it seems that pageX and pageY isn't usable on iOS.


Dec 15, 2011 at 5:57 AM // reply »
1 Comments

Thank you Ben Nadal for providing us a useful knowledge, but I have some concerns about using the PageX,Y as a standard relative.

I mean that if I have to show something relative to viewport and also under the mouse hover (mouse position relative to view ports' x and y-axis), In that case how can I find the mouse position relative to viewport, if I use e.pageY then it will return me the coordinate related to the full browser?

Thanks,
Hussain


Jan 16, 2012 at 1:19 AM // reply »
1 Comments

good one.....


Jan 27, 2013 at 2:13 AM // reply »
1 Comments

Thanks buddy. I landed on the right page to find out the difference between client and page arguments of mousemove method. This is helpful to many. The point is revealed in detail...GREAT!


Jan 28, 2013 at 3:19 AM // reply »
2 Comments

Hey Ben,

I am trying to modify the Method Draw application developed by MacKay.
Its using jQuery as its library and i am completely baffled with a problem for some time now. You do seem to somehow explained a solution to my problem here.

I want to track the mouse coordinates relative to the viewbox(the canvas) in this application using jquery and display this coordinates on a label that follows the mouse cursor. I want this to happen each time the user hovers over the viewbox(the canvas). I dont want the coordinates to be displayed when the user clicks on the canvas but rather when the user hovers over the canvas.

You think that would be possible using the solutions you described above?


Jan 28, 2013 at 3:20 AM // reply »
2 Comments

Sorry forgot a link to the applicaton here. Here it is. editor.method.ac


Mar 22, 2013 at 10:43 AM // reply »
1 Comments

Excellent! First explanation that is straightforward and does not just copy the definitions from other sites!


May 13, 2013 at 9:32 PM // reply »
1 Comments

Does anyone know why jQuery doesn't give us pageX, PageY on dragover events, at least in Chrome? The original event has a clientX and clientY.



Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 25, 2013 at 10:01 PM
My Experience With AngularJS - The Super-heroic JavaScript MVW Framework
@Avi, Really glad to help! @Jaredwilli, I'm finding a this image hits home with a lot of people :) Hopefully we can all work through the rough patches together! @Prateek, AngularJS has error ... read »
May 25, 2013 at 9:53 PM
Nested Views, Routing, And Deep Linking With AngularJS
@Mrsean2k, I'm glad I could help! I haven't been able to keep up with the ui-router stuff. I keep saying that I'll carve out time, but I just haven't gotten to it :( ... read »
May 25, 2013 at 9:49 PM
What If All User Interface (UI) Data Came In Reports?
@Jonah, Thanks for the book recommendations. I am looking them up right now. I can see that Object Thinking is available for the Kindle App - sweet! Also, I just recently heard Martin Fowler on the ... read »
May 25, 2013 at 9:41 PM
HashKeyCopier - An AngularJS Utility Class For Merging Cached And Live Data
@Chris, I'm super excited to hear that my posts are helpful. I am also loving AngularJS; but, it definitely has some caveats and some odd behaviors and some things that just don't seem to "wor ... read »
May 25, 2013 at 9:36 PM
Ask Ben: Manually Enforcing Basic HTTP Authorization In ColdFusion
@Adam, @Jason, After reading these comments, I double-checked my latest implementation and I am happy to report that I am using listFirst() and listRest(). ... read »
May 25, 2013 at 9:31 PM
Using "//" And ".//" Expressions In XPath XML Search Directives In ColdFusion
@Daxesh, I am not sure I understand the question about the current node. If you already have a reference to the current node, why would you need to query for it? As for parent node, I believe that ... read »
May 25, 2013 at 10:08 AM
Using "//" And ".//" Expressions In XPath XML Search Directives In ColdFusion
@Ben, my question is that i want the current node with its tag and its parent node. i just want only that data. So, give me the solution for that. and remember solution is working on " xpath 1.0 ... read »
May 25, 2013 at 10:01 AM
Using "//" And ".//" Expressions In XPath XML Search Directives In ColdFusion
hey ben, i want get my current node tag and also want the root node tag withing. So, how can i fix it.. ! ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools