我想知道如何在JavaScript中获取img和div等HTML元素的X和Y位置。


当前回答

我是这样做的,所以它与旧浏览器兼容。

// For really old browser's or incompatible ones
    function getOffsetSum(elem) {
        var top = 0,
            left = 0,
            bottom = 0,
            right = 0

         var width = elem.offsetWidth;
         var height = elem.offsetHeight;

        while (elem) {
            top += elem.offsetTop;
            left += elem.offsetLeft;
            elem = elem.offsetParent;
        }

         right = left + width;
         bottom = top + height;

        return {
            top: top,
            left: left,
            bottom: bottom,
            right: right,
        }
    }

    function getOffsetRect(elem) {
        var box = elem.getBoundingClientRect();

        var body = document.body;
        var docElem = document.documentElement;

        var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop;
        var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft;

        var clientTop = docElem.clientTop;
        var clientLeft = docElem.clientLeft;


        var top = box.top + scrollTop - clientTop;
        var left = box.left + scrollLeft - clientLeft;
        var bottom = top + (box.bottom - box.top);
        var right = left + (box.right - box.left);

        return {
            top: Math.round(top),
            left: Math.round(left),
            bottom: Math.round(bottom),
            right: Math.round(right),
        }
    }

    function getOffset(elem) {
        if (elem) {
            if (elem.getBoundingClientRect) {
                return getOffsetRect(elem);
            } else { // old browser
                return getOffsetSum(elem);
            }
        } else
            return null;
    }

有关JavaScript中坐标的更多信息,请点击此处:http://javascript.info/tutorial/coordinates

其他回答

正确的方法是使用element.getBoundingClientRect():

var rect = element.getBoundingClientRect();
console.log(rect.top, rect.right, rect.bottom, rect.left);

Internet Explorer一直支持这一点,只要您可能关心,它最终在CSSOM视图中被标准化。 所有其他浏览器早就采用了它。

一些浏览器还返回高度和宽度财产,尽管这是非标准的。如果您担心较旧的浏览器兼容性,请检查此答案的修订版,以获得优化的降级实现。

element.getBoundingClientRect()返回的值与视口相关。如果需要相对于另一个元素使用,只需从另一个矩形中减去一个矩形即可:

var bodyRect = document.body.getBoundingClientRect(),
    elemRect = element.getBoundingClientRect(),
    offset   = elemRect.top - bodyRect.top;

alert('Element is ' + offset + ' vertical pixels from <body>');

如果您使用jQuery,这可能是一个简单的解决方案:

<script>
  var el = $("#element");
  var position = el.position();
  console.log( "left: " + position.left + ", top: " + position.top );
</script>

这是我所创建的最好的代码(与jQuery的offset()不同,也可以在iframes中使用)。看起来webkit有点不同的行为。

基于meouw的评论:

function getOffset( el ) {
    var _x = 0;
    var _y = 0;
    while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) ) {
        _x += el.offsetLeft - el.scrollLeft;
        _y += el.offsetTop - el.scrollTop;
        // chrome/safari
        if ($.browser.webkit) {
            el = el.parentNode;
        } else {
            // firefox/IE
            el = el.offsetParent;
        }
    }
    return { top: _y, left: _x };
}

要获得元素的总偏移量,可以递归地对所有父偏移量求和:

function getParentOffset(el): number {
if (el.offsetParent) {
    return el.offsetParent.offsetTop + getParentOffset(el.offsetParent);
} else {
    return 0;
}
}

使用该实用函数,dom元素的总顶部偏移量为:

el.offsetTop + getParentOffset(el);

由于不同的浏览器以不同的方式呈现边框、填充、边距等。我编写了一个小函数来检索每个根元素中特定元素的顶部和左侧位置,您需要精确的维度:

function getTop(root, offset) {
    var rootRect = root.getBoundingClientRect();
    var offsetRect = offset.getBoundingClientRect();
    return offsetRect.top - rootRect.top;
}

对于检索左侧位置,必须返回:

    return offsetRect.left - rootRect.left;