Grauw’s blog

Browsers disagree quite vehemently on what constitutes the ‘view port element’, whether it is the body or the html element. Unfortunately you do need to know this from time to time, for example because the the clientX and clientY properties on the mouse event object specify coordinates relative to the view port scroll position.

I did some tests a while ago of what element the scrollTop is set on, and because I can not find any clear overview of when the view port is what elsewhere, I guess I might as well publish the results here:

Test results
Browser scrollTop is set on scrollTop in quirks mode
Internet Explorer 6 documentElement body
Internet Explorer 8 (IE7 mode) documentElement body
Internet Explorer 8 documentElement body
Firefox 3.0 documentElement body
Firefox 3.6 documentElement body
Safari 3 body body
Safari 4 body body
Chrome 3 body body
Chrome 4 body body
Opera 9.6 documentElement body
Opera 10 documentElement body

The testcase (quirks mode version).

Hopefully the WebKit folks will fix this inconsistency sometime soon, because the way it is now makes it kind of hard to implement a reliable future-proof generic getViewPort() method.

Probably the most robust way to determine the X and Y coordinates of a mouse event within the page is to leverage the non-standard pageX and pageY properties that most browsers support, and fall back to using clientX and clientY otherwise:

if ('pageX' in event && 'pageY' in event) {
    return new Point(event.pageX, event.pageY);
} else {
    var oDocument = (event.target || event.srcElement).ownerDocument;
    var oViewport = oDocument.compatMode == 'BackCompat' ?
                        oDocument.body : oDocument.documentElement;
    return new Point(
        oViewport.scrollLeft + event.clientX,
        oViewport.scrollTop + event.clientY
    );
}

p.s. relating to my previous post, note that I do use feature detection here for pageX and pageY. Didn’t mean to say feature detection is useless, just that it is not always the right solution, unlike what is preached by some.

Here I make an assumption that pageX, when/if implemented in IE, will be implemented correctly. Actually, given that this is a non-standardised property, perhaps it is not the most safe assumption to make. But then again, the property seems so simple, what could possibly go wrong. Right? Right? *Prepares to revisit this code snippet once IE9 is released…* :)

Grauw

Comments

the correct values by Softonic at 2015-11-03 10:28

I noticed, that in IE 10 when the event ondragover is fired the values of the attributes clientX, clientY, pageX, pageY, dataTransfer.getData are not refreshed when the mouse is moved. It works in all other IEs and even the metro browser acts like expected. Does anyone know how to get the correct values in IE 10?