I had to fix a strange bug today in the iBegin Share widget. On one of our pages (the readme specifically) it was positioning wrong. The goal was to position it 5px below the bottom of the object it’s attached to. Easily enough I was able to Google and find the same 10 results that said “here is what you do to get the *correct* absolute positions for an object”. None of them actually worked ![]()
So, too many hours later, and after not having a single person being able to clue me in on the problem, I found the issue. We had a container which had position: relative; and border-width: 25px 0;. To my suprise, the 25px border was what wasnt being counted. This didn’t seem to happen in Internet Explorer, only Firefox (and I believe Opera as well). I now give you a fully* (I guarantee nothing) working version of the getXY function.
Update: After doing a little bit more research this may be related to the hasLayout style property.
(You can also grab this over at PasteThat)
/** * Returns the absolute X and Y positions of an object. * @param {HTMLObject} obj HTML Object. * @return {Object} Returns an accessor with .x and .y values. */ function getXY(obj) { var curleft = 0; var curtop = obj.offsetHeight + 5; var border; if (obj.offsetParent) { do { // XXX: If the element is position: relative we have to add borderWidth if (getStyle(obj, 'position') == 'relative') { if (border = _pub.getStyle(obj, 'border-top-width')) curtop += parseInt(border); if (border = _pub.getStyle(obj, 'border-left-width')) curleft += parseInt(border); } curleft += obj.offsetLeft; curtop += obj.offsetTop; } while (obj = obj.offsetParent) } else if (obj.x) { curleft += obj.x; curtop += obj.y; } return {'x': curleft, 'y': curtop}; } /** * Returns the specified computed style on an object. * @param {HTMLObject} obj HTML Object * @param {String} styleProp Property name. * @return {Mixed} Computed style on object. */ function getStyle(obj, styleProp) { if (obj.currentStyle) return obj.currentStyle[styleProp]; else if (window.getComputedStyle) return document.defaultView.getComputedStyle(obj,null).getPropertyValue(styleProp); }
1 Responses to "Get X/Y Offsets for an Object in JavaScript"
Thank you! I thought I was going crazy when the “standard” X/Y javascript functions simply didn’t work.
There seems to be a bit of debug code left in your sample above, below is a slightly modified version that works for me.
I’ve also added support for object padding, which also causes the co-ordinates to be off.
Finally, i found that an object may not be set to position=relative, so I changed the logic to be != absolute.
/**
* Returns the absolute X and Y positions of an object.
* @param {HTMLObject} obj HTML Object.
* @return {Object} Returns an accessor with .x and .y values.
*/
function getXY(obj)
{
var curleft = 0;
var curtop = 0;
var border;
var padding;
if (obj.offsetParent)
{
do
{
// XXX: If the element is position: relative we have to add borderWidth
if (getStyle(obj, ‘position’) != ‘absolute’)
{
if (border = getStyle(obj, ‘border-top-width’)) curtop += parseInt(border);
if (border = getStyle(obj, ‘border-left-width’)) curleft += parseInt(border);
if (padding = getStyle(obj, ‘padding-top’)) curtop += parseInt(padding);
if (padding = getStyle(obj, ‘padding-left’)) curleft += parseInt(padding);
}
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
}
while (obj = obj.offsetParent)
}
else if (obj.x)
{
curleft += obj.x;
curtop += obj.y;
}
return {’x': curleft, ‘y’: curtop};
}
Leave A Reply