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


当前回答

我发现的最干净的方法是jQuery的偏移所使用的技术的简化版本。与其他一些答案类似,它从getBoundingClientRect开始;然后,它使用窗口和documentElement来调整滚动位置以及正文上的边距(通常是默认值)。

var rect = el.getBoundingClientRect();
var docEl = document.documentElement;

var rectTop = rect.top + window.pageYOffset - docEl.clientTop;
var rectLeft = rect.left + window.pageXOffset - docEl.clientLeft;

var els=文档.getElementsByTagName(“div”);var docEl=文档.documentElement;对于(var i=0;i<els.length;i++){var rect=els[i].getBoundingClientRect();var rectTop=rect.top+window.pageYOffset-docEl.clientTop;var rectLeft=rect.left+window.pageXOffset-docEl.clientLeft;els[i].innerHTML=“<b>”+rectLeft+“,”+rectTop+“</b>”;}第二部分{宽度:100px;高度:100px;背景色:红色;边框:1px实心黑色;}#相关{位置:相对;左:10px;顶部:10px;}#绝对值{位置:绝对;顶部:250px;左:250px;}<div id=“rel”></div><div id=“abs”></div><div></div>

其他回答

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

// 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

这样怎么样,通过传递元素的ID,它将返回左侧或顶部,我们还可以组合它们:

1) 查找左侧

function findLeft(element) {
  var rec = document.getElementById(element).getBoundingClientRect();
  return rec.left + window.scrollX;
} //call it like findLeft('#header');

2) 查找顶部

function findTop(element) {
  var rec = document.getElementById(element).getBoundingClientRect();
  return rec.top + window.scrollY;
} //call it like findTop('#header');

或3)找到左侧和顶部

function findTopLeft(element) {
  var rec = document.getElementById(element).getBoundingClientRect();
  return {top: rec.top + window.scrollY, left: rec.left + window.scrollX};
} //call it like findTopLeft('#header');

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

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

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

    return offsetRect.left - rootRect.left;

虽然这很可能会在这么多答案的底部丢失,但这里的顶级解决方案并不适合我。据我所知,其他答案都没有帮助。情况:在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 getOffset(el) {
  const rect = el.getBoundingClientRect();
  return {
    left: rect.left + window.scrollX,
    top: rect.top + window.scrollY
  };
}

使用此选项,我们可以获得X位置:

getOffset(element).left

…或Y位置:

getOffset(element).top