52

I need to get the X,Y coordinates (relative to the document's top/left) for a DOM element. I can't locate any plugins or jQuery property or method that can give these to me. I can get the top and left of the DOM element, but that can be either relative to its current container/parent or to document.

DMCS
  • 31,720
  • 14
  • 71
  • 104

3 Answers3

95

you can use Dimensions plugin [Deprecated... included in jQuery 1.3.2+]

offset()
Get the current offset of the first matched element, in pixels, relative to the document.

position()
Gets the top and left position of an element relative to its offset parent.

knowing this, then it's easy... (using my little svg project as an example page)

var x = $("#wrapper2").offset().left;
var y = $("#wrapper2").offset().top;

console.log('x: ' + x + ' y: ' + y);

output:

x: 53 y: 177

hope it helps what you're looking for.

here's an image of offset() and position()

using XRay

alt text

using Web Developer toolbar

alt text

Community
  • 1
  • 1
balexandre
  • 73,608
  • 45
  • 233
  • 342
  • See: http://docs.jquery.com/Plugins/dimensions "Deprecated: As of jQuery 1.2.6, the dimensions plugin has been merged into core. You can view the full documentation in the CSS category. " plus, this is only relative positions – DMCS Jun 16 '09 at 17:54
  • if you run that code on that page of the project you can verify that is not relative but they are absolute values. – balexandre Jun 16 '09 at 17:57
  • Looks like they've resolved the issues in a newer release of jQuery. Using 1.3.2 seems to give the document x,y coordinates like I was hoping. And I tested this in IE7, FF3 and Safari3 and they all seem to be behaving correctly – DMCS Jun 16 '09 at 18:12
  • 1
    Just came across another abnormality. It doesn't account for margins of the element you're selecting. So to get the visual x,y of the viewable element...I'm going to need to add those on. – DMCS Jun 16 '09 at 18:45
  • it does... in my example (1st image) if you add in the first line this: $("#wrapper2").css("marginLeft","20px"); and then execute the x and y variables, you will end up with: x: 73 y: 177 – balexandre Jun 16 '09 at 18:58
  • 1
    @balexandre do you think you could help me with this question : http://stackoverflow.com/questions/19100184/jsrender-how-to-call-an-external-template-from-a-nested-template – eddy Sep 30 '13 at 17:49
7

My solution is a plugin with "workarounds" :+D . But Works!

jQuery.fn.getPos = function(){
        var o = this[0];
        var left = 0, top = 0, parentNode = null, offsetParent = null;
        offsetParent = o.offsetParent;
        var original = o;
        var el = o;
        while (el.parentNode != null) {
            el = el.parentNode;
            if (el.offsetParent != null) {
                var considerScroll = true;
                if (window.opera) {
                    if (el == original.parentNode || el.nodeName == "TR") {
                        considerScroll = false;
                    }
                }
                if (considerScroll) {
                    if (el.scrollTop && el.scrollTop > 0) {
                        top -= el.scrollTop;
                    }
                    if (el.scrollLeft && el.scrollLeft > 0) {
                        left -= el.scrollLeft;
                    }
                }
            }            
            if (el == offsetParent) {
                left += o.offsetLeft;
                if (el.clientLeft && el.nodeName != "TABLE") {
                    left += el.clientLeft;
                }
                top += o.offsetTop;
                if (el.clientTop && el.nodeName != "TABLE") {
                    top += el.clientTop;
                }
                o = el;
                if (o.offsetParent == null) {
                    if (o.offsetLeft) {
                        left += o.offsetLeft;
                    }
                    if (o.offsetTop) {
                        top += o.offsetTop;
                    }
                }
                offsetParent = o.offsetParent;
            }
        }
        return {
            left: left,
            top: top
        };
    };

Usage:

var p = $("#wrapper2").getPos();
alert("top:"+p.top+"; left:"+p.left);
EderBaum
  • 993
  • 13
  • 16
  • 8
    you know that there are frameworks just so we don't need to re-write code, right? – balexandre Apr 20 '10 at 11:57
  • 10
    frameworks are great until you have to write a userscript. Or when you want to write a patch to jQuery; there are still reasons to know javascript. – Chuck Vose Mar 16 '11 at 23:49
4

The offset function will do that for you.

Here is the example they give:

var p = $("p:last");
var offset = p.offset();
p.html( "left: " + offset.left + ", top: " + offset.top );
Jeff Davis
  • 4,736
  • 4
  • 38
  • 44