Tuesday, October 09, 2007

Absolute position of html elements in Javascript

Update: in IE7 I noticed that the style property doesn't keep the inherited values or the CSS values, but only the inline values of style. 'currentStyle' keeps all values, therefore I used that too, in case style would not work.

Update: the same can be done in FireFox by using the document.defaultView.getComputedStyle(myObject, null) syntax equivalent to myObject.currentStyle in Internet Explorer. I have not updated my function to work with that, though.

Update: By adding a break in case of relative or absolute positioning I seemed to have fixed most of the issues regarding those types of positioned elements.

Whenever one wants to popup something with Javascript, the bigger problem arising is to find the absolute position of the element that you want the popup to cling to. Searching the web you will probably find a site like this: How to get an element’s position and area, you will try that solution and say "Wee! It works!" until you scroll something inside the page and everything turns to mush.

Analysing the code and the html you will see that it ignores completely the scrolling of various elements. Even worse, the offsetParent is one for Internet Explorer and another for FireFox. So here is my solution, which seems to work in most cases. I will work on it some more, but not in the near future and usually one doesn't need a popup in a popup. So here is the code:

function findPos(obj)
var curleft = 0;
var curtop = 0;
if (obj.offsetParent)
while (obj.offsetParent)
curleft += obj.offsetLeft-obj.scrollLeft;
curtop += obj.offsetTop-obj.scrollTop;
var position='';
if (obj.style&&obj.style.position)
if (!position)
if (obj.currentStyle && obj.currentStyle.position)
position = obj.currentStyle.position.toLowerCase();
if ((position=='absolute')||(position=='relative')) break;
while (obj.parentNode!=obj.offsetParent) {
curleft -= obj.scrollLeft;
curtop -= obj.scrollTop;
obj = obj.offsetParent;
else {
if (obj.x)
curleft += obj.x;
if (obj.y)
curtop += obj.y;
return {left:curleft,top:curtop};