查找元素相对于文档的位置

时间:2011-04-08 17:37:12

标签: javascript dom

确定相对于文档/正文/浏览器窗口的元素位置的最简单方法是什么?

现在我正在使用.offsetLeft/offsetTop,但此方法只为您提供相对于父元素的位置,因此您需要确定body元素的父项数,以了解与body相关的位置/浏览器窗口/文档位置。

这种方法也很麻烦。

9 个答案:

答案 0 :(得分:157)

您可以在不遍历DOM的情况下获取 top left

function getCoords(elem) { // crossbrowser version
    var box = elem.getBoundingClientRect();

    var body = document.body;
    var docEl = document.documentElement;

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

    var clientTop = docEl.clientTop || body.clientTop || 0;
    var clientLeft = docEl.clientLeft || body.clientLeft || 0;

    var top  = box.top +  scrollTop - clientTop;
    var left = box.left + scrollLeft - clientLeft;

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

答案 1 :(得分:61)

您可以使用element.getBoundingClientRect()检索相对于视口的元素位置。

然后使用document.documentElement.scrollTop计算视口偏移量。

两者的总和将给出相对于文档的元素位置:

element.getBoundingClientRect().top + document.documentElement.scrollTop

答案 2 :(得分:58)

您可以遍历offsetParent直到DOM的顶层。

function getOffsetLeft( elem )
{
    var offsetLeft = 0;
    do {
      if ( !isNaN( elem.offsetLeft ) )
      {
          offsetLeft += elem.offsetLeft;
      }
    } while( elem = elem.offsetParent );
    return offsetLeft;
}

答案 3 :(得分:6)

document-offset第三方脚本)很有意思,似乎可以利用其他答案的方法。

实施例

var offset = require('document-offset')
var target = document.getElementById('target')
console.log(offset(target))
// => {top: 69, left: 108} 

答案 4 :(得分:4)

我建议使用

element.getBoundingClientRect()
建议here

而不是通过 offsetLeft offsetTop offsetParent 进行手动偏移计算。按照提议here 在某些情况下*手动遍历会产生无效结果。请参阅此Plunker:http://plnkr.co/pC8Kgj

*当元素位于具有静态(=默认)定位的可滚动父级内时。

答案 5 :(得分:2)

对于那些想要获取元素各个位置的x和y坐标的人,相对于文档。

const getCoords = (element, position) => {
  const { top, left, width, height } = element.getBoundingClientRect();
  let point;
  switch (position) {
    case "top left":
      point = {
        x: left + window.pageXOffset,
        y: top + window.pageYOffset
      };
      break;
    case "top center":
      point = {
        x: left + width / 2 + window.pageXOffset,
        y: top + window.pageYOffset
      };
      break;
    case "top right":
      point = {
        x: left + width + window.pageXOffset,
        y: top + window.pageYOffset
      };
      break;
    case "center left":
      point = {
        x: left + window.pageXOffset,
        y: top + height / 2 + window.pageYOffset
      };
      break;
    case "center":
      point = {
        x: left + width / 2 + window.pageXOffset,
        y: top + height / 2 + window.pageYOffset
      };
      break;
    case "center right":
      point = {
        x: left + width + window.pageXOffset,
        y: top + height / 2 + window.pageYOffset
      };
      break;
    case "bottom left":
      point = {
        x: left + window.pageXOffset,
        y: top + height + window.pageYOffset
      };
      break;
    case "bottom center":
      point = {
        x: left + width / 2 + window.pageXOffset,
        y: top + height + window.pageYOffset
      };
      break;
    case "bottom right":
      point = {
        x: left + width + window.pageXOffset,
        y: top + height + window.pageYOffset
      };
      break;
  }
  return point;
};

用法

  • getCoords(document.querySelector('selector'), 'center')

  • getCoords(document.querySelector('selector'), 'bottom right')

  • getCoords(document.querySelector('selector'), 'top center')

答案 6 :(得分:2)

我发现以下方法在处理偏移offsetTop / offsetLeft的边缘情况时最可靠。

function getPosition(element) {
    var clientRect = element.getBoundingClientRect();
    return {left: clientRect.left + document.body.scrollLeft,
            top: clientRect.top + document.body.scrollTop};
}

答案 7 :(得分:1)

http://www.quirksmode.org/js/findpos.html解释最好的方法,总而言之,你在正确的轨道上,你必须找到偏移量并遍历父母的树。

答案 8 :(得分:1)

如果您不介意使用jQuery,那么您可以使用%功能。如果您想了解有关此功能的更多信息,请参阅documentation