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


当前回答

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

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

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

el.offsetTop + getParentOffset(el);

其他回答

如果使用jQuery,维度插件非常出色,可以让您精确地指定所需内容。

e.g.

相对位置,绝对位置,无填充的绝对位置,有填充。。。

继续下去,让我们说你可以用它做很多事情。

另外,使用jQuery的好处是它的文件大小很小,使用起来很方便,以后如果没有它,就不会返回JavaScript。

这是一个使用vanilla JS递归迭代element.offsetTop和element.ooffsetParent的现代1行代码:

功能:

getTop = el => el.offsetTop + (el.offsetParent && getTop(el.offsetParent))

用法:

const el = document.querySelector('#div_id');
const elTop = getTop(el)

优势:

无论当前滚动位置如何,始终返回绝对垂直偏移。


传统语法:

function getTop(el) {
  return el.offsetTop + (el.offsetParent && getTop(el.offsetParent));
}

正确的方法是使用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>');

我接受了@meouw的回答,添加到允许边界的clientLeft中,然后创建了三个版本:

getAbsoluteOffsetFromBody-类似于@meouw,它获取相对于文档的body或html元素的绝对位置(取决于quicks模式)

getAbsoluteOffsetFromGivenElement-返回相对于给定元素的绝对位置(relativeEl)。注意,给定的元素必须包含元素el,否则其行为将与getAbsoluteOffsetFromBody相同。如果在另一个(已知)元素中包含两个元素(可选地,节点树上的多个节点),并且希望使它们处于相同的位置,则这非常有用。

getAbsoluteOffsetFromRelative-返回相对于具有position:relative的第一个父元素的绝对位置。这与getAbsoluteOffsetFromGivenElement类似,原因相同,但仅限于第一个匹配元素。

getAbsoluteOffsetFromBody = function( el )
{   // finds the offset of el from the body or html element
    var _x = 0;
    var _y = 0;
    while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) )
    {
        _x += el.offsetLeft - el.scrollLeft + el.clientLeft;
        _y += el.offsetTop - el.scrollTop + el.clientTop;
        el = el.offsetParent;
    }
    return { top: _y, left: _x };
}

getAbsoluteOffsetFromGivenElement = function( el, relativeEl )
{   // finds the offset of el from relativeEl
    var _x = 0;
    var _y = 0;
    while( el && el != relativeEl && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) )
    {
        _x += el.offsetLeft - el.scrollLeft + el.clientLeft;
        _y += el.offsetTop - el.scrollTop + el.clientTop;
        el = el.offsetParent;
    }
    return { top: _y, left: _x };
}

getAbsoluteOffsetFromRelative = function( el )
{   // finds the offset of el from the first parent with position: relative
    var _x = 0;
    var _y = 0;
    while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) )
    {
        _x += el.offsetLeft - el.scrollLeft + el.clientLeft;
        _y += el.offsetTop - el.scrollTop + el.clientTop;
        el = el.offsetParent;
        if (el != null)
        {
            if (getComputedStyle !== 'undefined')
                valString = getComputedStyle(el, null).getPropertyValue('position');
            else
                valString = el.currentStyle['position'];
            if (valString === "relative")
                el = null;
        }
    }
    return { top: _y, left: _x };
}

如果您仍然有问题,特别是与滚动有关的问题,您可以尝试查看http://www.greywyvern.com/?post=331-我注意到getStyle中至少有一段有问题的代码,假设浏览器运行正常,这段代码应该是不错的,但根本没有测试其他代码。

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

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