Position and Visibility

To find the absolute position of an element on a page you have to look at more than just the offsetLeft and offsetTop. You have to look at its parents as well.

function findAbsolutePosition(elem) {

var pos = {x: 0, y: 0};

while (elem) {

pos.x += elem.offsetLeft;

pos.y += elem.offsetTop;

elem = elem.offsetParent; // Note its offsetParent not parentNode.

}

return pos;

}

Update: After playing with some of these, I found the offsetLeft and offsetTop do not work on elements that have various CSS3 properties on them like column-width or transform. To get around it, we can use getClientRect and (to account for scroll offset) pageXOffset:

function findAbsolutePosition(elem) {

var clientRect = elem.getClientRects()[0];

return {x: clientRect.left + window.pageXOffset,

y: clientRect.top + window.pageYOffset};

}

This has the added benefit of not only working on CSS3 transformed objects, but also is faster to compute.

Finding visibility requires similar things but is much harder since there are many ways to make an object "invisible" that are not display:none or visibility:hidden. We basically work up the parent nodes again looking to see if we are display:none'd. We use getComputedStyle which will tell us if it happened regardless of it being in the .style or it coming from a <style> defined CSS class or something.

https://developer.mozilla.org/en/DOM:window.getComputedStyle

function isVisible(elem) {

var originalElement = elem;

while (elem) {

var style = document.defaultView.getComputedStyle(elem, null);

if (style.getPropertyValue('display') == 'none' ||

style.getPropertyValue('visibility') == 'hidden') {

break;

}

// Note: getComputedStyle only works on elements not all nodes.

elem = elem.parentElement;

}

// We also check position < 0, but if you don't care about than just stop

// at this check.

if (!elem) {

return true;

}

var pos = findAbsolutePosition(originalElement);

return pos.x >= 0 && pos.y >= 0;

}