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


当前回答

虽然这很可能会在这么多答案的底部丢失,但这里的顶级解决方案并不适合我。据我所知,其他答案都没有帮助。情况:在HTML5页面中,我有一个菜单,它是页眉中的导航元素(不是页眉,而是另一个元素中的页眉)。我希望一旦用户滚动到顶部,导航就一直保持在顶部,但在此之前,标题是绝对定位的(所以我可以让它稍微覆盖一些其他内容)。上述解决方案从未触发过更改,因为.offsetTop不会更改,因为这是一个绝对定位的元素。此外,scrollTop属性只是最顶部元素的顶部。。。也就是说0并且总是0。我使用这两个(以及getBoundingClientRect结果)执行的任何测试都不会告诉我导航栏的顶部是否曾滚动到可查看页面的顶部(再次,正如控制台中所报告的那样,它们只是在滚动时保持相同的数字)。

解决方案我使用的解决方案

window.visualViewport.pageTop

pageTop属性的值反映了屏幕的可视部分,因此允许我跟踪元素相对于可视区域边界的位置。

也许没必要说,每当我处理滚动时,我都希望使用这个解决方案以编程方式响应正在滚动的元素的移动。希望它能帮助其他人。重要提示:这似乎在Chrome和Opera中有效,在Firefox(6-2018)中肯定不行。。。在Firefox支持visualViewport之前,我建议不要使用这种方法(我希望他们很快会使用……这比其他方法更有意义)。更新:请注意此解决方案。虽然我仍然发现我发现的对于“……以编程方式响应滚动元素的移动”的情况非常有用。我遇到的问题的更好解决方案是使用CSS在元素上设置位置:粘滞。使用sticky,您可以在不使用javascript的情况下让一个元素保持在顶部(注意:有时这不会像将元素更改为固定的那样有效,但对于大多数情况,sticky方法可能会更好)更新01:所以我意识到,对于不同的页面,我需要在一个稍微复杂的滚动设置中检测元素的位置(视差加上作为消息一部分滚动经过的元素)。在这种情况下,我意识到以下内容提供了我用来确定何时做某事的价值:

  let bodyElement = document.getElementsByTagName('body')[0];
  let elementToTrack = bodyElement.querySelector('.trackme');
  trackedObjPos = elementToTrack.getBoundingClientRect().top;
  if(trackedObjPos > 264)
  {
    bodyElement.style.cssText = '';
  }

希望这个答案现在更有用。

其他回答

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

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

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

el.offsetTop + getParentOffset(el);

这很简单,在JS中有两行:

var elem = document.getElementById("id");    
alert(elem.getBoundingClientRect());

我想我也会把这个扔出去。我还不能在旧版浏览器中测试它,但它在前3名中的最新版本中运行。:)

Element.prototype.getOffsetTop = function() {
    return ( this.parentElement )? this.offsetTop + this.parentElement.getOffsetTop(): this.offsetTop;
};
Element.prototype.getOffsetLeft = function() {
    return ( this.parentElement )? this.offsetLeft + this.parentElement.getOffsetLeft(): this.offsetLeft;
};
Element.prototype.getOffset = function() {
    return {'left':this.getOffsetLeft(),'top':this.getOffsetTop()};
};

为了获得元素的精确偏移量,库会进行一定的长度。这里有一个简单的函数,它在我尝试过的所有情况下都能完成任务。

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;
        el = el.offsetParent;
    }
    return { top: _y, left: _x };
}
var x = getOffset( document.getElementById('yourElId') ).left; 

我可以像element.offsetLeft或element.ooffsetTop一样。示例:document.getElementById('profileImg').offsetLeft