Finding the absolute position of an element – when in a table in a scrollable div

I have just spent two hours on a stupidity with finding the position of an element which is inside a table which is inside a scrollable div, because offsetParent does not correctly identify the next offsetParent element (it does not find any scrollable divs above a table). It jumps straight to the body tag.

My Solution:

/**
 * Return the position of the given element in an x/y array.
 */
function getPosition(element) {
    var xPosition = 0;
    var yPosition = 0;

    while(element && element != null) {
        xPosition += element.offsetLeft;
        xPosition -= element.scrollLeft;
        xPosition += element.clientLeft;

        yPosition += element.offsetTop;
        yPosition -= element.scrollTop;
        yPosition += element.clientTop;

        // if the element is a table, extra processing 
        // as offsetParent will skip scrollable divs
        if (element.nodeName == 'TABLE') {
            var prevelement = element;
            var nextelement = element.parentNode;

            // find any scrolls between the previous element
            // and the supposed next offsetParent.
            while(nextelement != prevelement.offsetParent) {
                yPosition -= nextelement.scrollTop;
                xPosition -= nextelement.scrollLeft;
                nextelement = nextelement.parentNode;
            }
        }

        element = element.offsetParent;
    }

    return { x: xPosition, y: yPosition };
}

Hope it helps someone else.

This has been tested in:
IE 9        – 9.0.8112.16421
Firefox – 18.0.1
Chrome – 24.0.1312.57 m
Opera    – 12.11 (1161)

Leave a Reply

You must be logged in to post a comment.