Find the position of an element in the DOM [Javascript]
I ran into a problem of placing an element I created via javascript, it was a calender for a date picker. I wanted the calender to appear directly under the textbox that would accept the selection from the user. This is a deceptively tricky thing to do on websites. This is because it doesn’t store the Top and Left of the element relative to the Top/Left of the current window, rather it stores the Top and Left relative to it’s offsetParent. What’s an offsetParent? It’s the property of an element whose parent affects it’s positioning, this can be it’s actual parent but it can also be a parent further up the tree depending on if it affects its offsetLeft and offsetTop peroperties. If an element is positioned fixed its offsetParent will be null, so you won’t always have to traverse to the top of the DOM tree to get the actual offset of your element relative to the window.
Most sites on the web will give you something similar to the following code to calculate the offsetLeft and offsetRight offsetTop of an element:
-
-
function getPosition(el){
-
if( ‘undefined’ != typeof( el.offsetParent ) ){
-
for( var x = 0, y =0; el; el = el.offsetParent ){
-
x += el.offsetLeft;
-
y += el.offsetTop;
-
}
-
return [ x, y ];
-
}else{
-
//there is no offsetParent here so just
-
//send back the elements position
-
return [ el.x, el.y ];
-
}
-
}
-
This is great and it will suit you for the vast majority of your needs. However, there is a problem, if your element is contained within an element that has a scroll, it will not take that into account and when you got to display whatever element you’ve used it will place it in the position on the window where it would have been had the parent element not been scrollable. This frustrated me for quite some time simply because when it displayed my calender it was displaying out of my view and the overall document wouldn’t create a scroll bar down to it so it seemed to me like it wasn’t displaying at all. Eventually I figured out it was displaying, just not within my view, I thought it might be the z-index but no it wasn’t. Finally after looking over the DOM spec I figured out what it was and it’s such a simple fix I’m surprised I don’t see it included on more tutorials.
Such an amazingly simple fix is that there is another property of elements called the scrollTop and scrollLeft, I imagine if you have any sort of cognative abilities you can garner the function of these properties. So how do you implement this?
-
-
function getPosition(el){
-
if( ‘undefined’ != typeof( el.offsetParent ) ){
-
for( var x = 0, y =0, sX = 0, sY = 0; el; el = el.offsetParent ){
-
sX = el.scrollLeft ? el.scrollLeft : 0;
-
sY = el.scrollTop ? el.scrollTop : 0;
-
x += el.offsetLeft - sX;
-
y += el.offsetTop - sY;
-
}
-
return [ x, y ];
-
}else{
-
//there is no offsetParent here so just
-
//send back the elements position
-
return [ el.x, el.y ];
-
}
-
}
-
Yup that’s it, you have to check and see if the element has the scrollLeft/Top properties, sometimes it’s null and will throw an exception if you try to perform math operations with it, which is why we used the ternary operator to assign 0 to it if it’s null.
Technorati Tags: Javascript, Position, DOM, Element, offsetParent, offsetLeft, offsetTop, scrollLeft, scrollTop
Popularity: 88% [?]