Screen Coordinates of a element, via Javascript
Asked Answered
M

5

35

I'm trying to get the screen coordinates (that is, relative to the top left corner of the screen) of an element in a browser window. It's easy to get the size and position of the window (screenX, screenY) and it's easy (with jQuery) to get the offset of the element ($('element').offset().left).

However, I need to know how many pixels it is from the element all the way to the corner of the screen. I've found some things that appear to be specific to IE, but I'd like this to work in as many browsers as possible.

Edited to add a picture: alt text

Malefaction answered 25/2, 2010 at 21:32 Comment(0)
C
15

window.screenX/Y are not supported on IE. But for other browsers, a close approximation of position is:

var top = $("#myelement").offset().top + window.screenY;
var left = $("#myelement").offset().left + window.screenX;

Exact position depends on what toolbars are visible. You can use the outer/innerWidth and outer/innerHeight properties of the window object to approximate a little closer.

IE doesn't provide much in the way of window properties, but oddly enough, a click event object will provide you with the screen location of the click. So I suppose you could have a calibration page which asks the user to "click the red dot" and handle the event with

function calibrate(event){
    var top = event.screenY;
    var left = event.screenX;
}

Or possibly use the mouseenter/leave events using the coordinates of that event to calibrate. Though you'd have trouble determining if the mouse entered from the left, right, top, or bottom.

Of course, as soon as they move the screen you'll need to recalibrate.

For lots more on browser property compatibilities see PPK's Object Model tables.

Cureall answered 25/2, 2010 at 22:11 Comment(3)
Can you get the position of the mouse cursor relative to the element it's in, as well as the screen coords? Then calibration could really work.Malefaction
Hmmm, thinking about this more, I understand better what you meant. I think it would definitely work to calibrate, and it would only need to be redone if they changed their browser chrome.Malefaction
Thanks for pointing me in the right direction. Thinking in terms of doing this IN a click event in the page makes all the difference. With that context I can calculate the browser chrome offsets. And this works in IE. This is what I've come up with: (event.screenY - event.pageY) + $('#element').offset().top Which gives the screen Y of the element in question.Malefaction
B
7

I disagree with jvenema's answer.

I have found a solution that is working for me on google chrome anyway, but I hope that this will works on many other browsers too (maybe not on some old internet explorers).

Inside the <script> tags declare new two global variables called: pageX and pageY with the var keyword.

These global variables should always store the coordinates of the top left corner of the rendered page relative to the top left corner of the screen monitor, but in order to achieve this goal, the window.onmousemove should refers to a function that sets the pageX to the difference of event.screenX and event.clientX, and the pageY to the difference of event.screenY and event.clientY.

Then all what you need to do is to get the coordinates of an element (relative to the top left corner of the rendered page) and add pageX and pageY. The results of these expressions will be the coordinates of this element relative to the top left corner of the screen monitor!

Code example (only javascript):

<script>
    var pageX;
    var pageY;
    window.onmousemove = function (e) {
       pageX = e.screenX - e.clientX;
       pageY = e.screenY - e.clientY;
    }
    function getScreenCoordinatesOf(obj) {
       var p = {};
       p.x = pageX + obj.clientLeft;
       p.y = pageY + obj.clientTop;
       return p;
    }
</script>

Hope that helps!

Byzantine answered 25/1, 2015 at 13:33 Comment(1)
I dont like this - solution - writing millions of mousemoves away - it should be a browser thing ... But thanksfully I am not the only one using the pragmatic approach. so vote up. - and I have a complex thing running here (combination of HTML5 Canvas & SVG getting CTMs and so on, then "fiddling arround" with this only simple info! what is a getSceenCTM helpful, if i cant get Screen coordiantes?Intensifier
A
4

I don't think this is possible.

The element coordinates are relative to the top left corner of the rendered page.

The window coordinates are relative to the screen.

There is, to my knowledge, nothing that relates the top left corner of the rendered page to the top left corner of the window. So there's no way to account for borders, scrollbars, chrome, etc. So I think you're sunk on this one.

Alexi answered 25/2, 2010 at 22:6 Comment(0)
A
0

Here is how I am doing it.

const pos = {x:number, y:number}

const scrollY = window.scrollY;

const targetArea = window?.document?.elementFromPoint(
      pos.x,
      pos.y - scrollY
 );

This doesn't account for x scroll factor. I think this is basically what @joel said like 11 years ago

Asleep answered 22/10, 2022 at 5:1 Comment(0)
A
0

It was necessary to consider scaling for me, so
Windows 10 with Scaling, Firefox, screen pixels:

function getScreenPosPx(elem, posAtMiddle){
    // Returns absolute position in pixels (px) relative to screen corner
    // Tested only with W10 Firefox

    let rect = elem.getBoundingClientRect();
    let screen_scale = window.devicePixelRatio;

    // relative to page corner
    // i.e. not from window corner, skips window menu area
    let elem_x_px = (posAtMiddle? (rect.left + rect.right) / 2 : rect.x) * screen_scale;
    let elem_y_px = (posAtMiddle? (rect.bottom + rect.top) / 2 : rect.y) * screen_scale;

    // page corner relative to screen corner
    let page_x_px = window.mozInnerScreenX * screen_scale;
    let page_y_px = window.mozInnerScreenY * screen_scale;
    // cross-browser my closet find, hacky and incorrect by few px
    // expects borders of same width and no page footer at all
    // let page_x_px = (window.screenX + (window.outerWidth - window.innerWidth)/2) * screen_scale;
    // let page_y_px = (window.screenY + (window.outerHeight - window.innerHeight)) * screen_scale;

    let screen_x = Math.round(page_x_px + elem_x_px);
    let screen_y = Math.round(page_y_px + elem_y_px);

    return {x:screen_x, y:screen_y}
}
Alleras answered 18/5 at 11:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.