JavaScript中获取元素的绝对位置

在一些应用中,可能会有需要知道某一个控件在页面中的位置,在网上比较容易找到下面这个解决方法。

在页面中有一个按钮:

<input id=a type="button" 
    value="click me to get position" 
    onclick="getPos(this)"/>

在脚本中响应点击事件的是这个函数:

function getPos(e){
    var t=e.offsetTop;
    var l=e.offsetLeft;
    while(e=e.offsetParent){
        t+=e.offsetTop;
        l+=e.offsetLeft;
    }
    alert("top="+t+"\nleft="+l);
}

这个方法的实现相当精炼,意思就是先取得自己的相对位置,再叠加其最近的相对位置容器(offsetParent,它不一定是其父节点)的相对位置,直至顶层位置容器(一般就是body),从而得出该节点的相对位置。

不过,很快就发现这个函数也许并不够用,因为我在页面里有可能使用了一些CSS来使得本来平铺的画面变成一个滚动区域,例如设置了父节点的height为某个值,并且其overflow设为auto或者scroll。这时,上面的方法因为没有计算其滚动偏移,所以所得的值不一定是元素当前的绝对位置,所以我对上面的方法进行了一些小改动,实际上就是加入了对其滚动偏移量的计算。

function getPosition(sender) {
    var e=sender,E=e;
    var x=e.offsetLeft;
    var y=e.offsetTop;
    while (e=e.offsetParent) {
        var P=e.parentNode;
        while (P!=(E=E.parentNode)) {
            x-=E.scrollLeft;
            y-=E.scrollTop;
        }
        x+=e.offsetLeft;
        y+=e.offsetTop;
        E=e;
    }
    return {"x":x,"y":y};
    //alert("top="+y+"\nleft="+x);
}

稍微测试了一下,基本上在IE和FF中都能正常运转。

在运用方面,由于使用到往上遍历,如果节点树结构过于复杂,而且有不会有滚动出现的话,那么还是用第一个方法就足够了。

注:又是炒冷饭 -_-! 原作发表于 2007-09-08