views:

2305

answers:

4

There was a thread on this in comp.lang.javascript recently where victory was announced but no code was posted:

On an HTML page how do you find the lower left corner coordinates of an element (image or button, say) reliably across browsers and page styles? The method advocated in "Ajax in Action" (copy I have) doesn't seem to work in IE under some circumstances. To make the problem easier, let's assume we can set the global document style to be "traditional" or "transitional" or whatever.

Please provide code or a pointer to code please (a complete function that works on all browsers) -- don't just say "that's easy" and blather about what traversing the DOM -- if I want to read that kind of thing I'll go back to comp.lang.javascript. Please scold me if this is a repeat and point me to the solution -- I did try to find it.

A: 

Try this:

var elm = document.getElementById('foo');
var point = {x:0,y:elm.offsetHeight}; // Change to y:0 to get the top-left

while (elm)
{
    // This will get you the position relative to the absolute container,
    // which is what you need for positioning an element within it
    if (elm.style.position == 'absolute')
        break;

    point.x += elm.offsetLeft;
    point.y += elm.offsetTop;

    elm = elm.offsetParent;
}
Greg
Greg, this is what doesn't work (sometimes).
Aaron Watters
Can you give a concrete example of when it doesn't work?
Greg
Sure <a href=http://aaron.oirt.rutgers.edu/myapp/docs/W.intro>http://aaron.oirt.rutgers.edu/myapp/docs/W.intro</a>. If I try to position the footnotes using that algorithm on IE they show up off the page to the right.
Aaron Watters
Hmm it actually looks ok to me. It's hard to read your HTML but I notice you're using position:absolute, which could screw things up. I've modified the code - give that a try
Greg
A: 

In jQuery:

var jq = $('#yourElement');
var position = jq.offset();
alert('x: ' + position.left + ', y: ' + position.top);

var bottomLeftPixelPosition =
    { left: position.left, top: position.top + jq.height() - 1; };
Nathan Ridley
+1  A: 

In my experience, the only sure-fire way to get stuff like this to work is using JQuery (don't be afraid, it's just an external script file you have to include). Then you can use a statement like

$('#element').position()

or

$('#element').offset()

to get the current coordinates, which works excellently across any and all browsers I've encountered so far.

Udo
30k for that? Well, at least I can look and try to see how they implemented it -- assuming I can find an uncompressed source.
Aaron Watters
I just had a look at the JQuery source and the functions seem to be heavily interdependent. Too much so to extract just a few lines of code (at least for my taste). I usually hate people who do this, but I'm going to go ahead and become one now: JQuery will save you a lot of worries across the board and 30k is not really that much data for something that's going to be cached across requests anyway. Take it from someone who generally hates frameworks ;-)
Udo
A: 

I have been using this, works for both IE and Firefox.

var Target = document.getElementById('SomeID');
var Pos = findPos(Target);

AnotherObj = document.getElementById('AnotherID');
AnotherObj .style.top  = Pos[1] + "px";
AnotherObj .style.left = Pos[0] + "px";

//------------------------------------
function findPos(obj) {
//----------------------------------------
    var curleft = curtop = 0;
    if (obj.offsetParent) {
    do {
      curleft += obj.offsetLeft;
      curtop += obj.offsetTop;
    } while (obj = obj.offsetParent);
    return [curleft,curtop];
    }
}
MarkKneen
As mentioned, this does not work consistently. It may be that if I use "strict" html or whatever that it will start working. Please inform if that is the trick. The jquery library seems to indicate that you also need to take things like margins into account, which aren't handled by the above.
Aaron Watters