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

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

现在我使用的是 .offsetLeft/offsetTop,但是这个方法只给出了相对于父元素的位置,所以您需要确定 body 元素的父元素数,以便知道相对于 body/浏览器窗口/文档位置的位置。

这种方法也很麻烦。

174962 次浏览

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

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

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

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

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

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

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

我建议用

element.getBoundingClientRect()

正如此处所建议的那样 取代了 左偏移偏移顶部补偿父母的人工偏移计算 在某些情况下 * 手动遍历会产生无效的结果,请参阅 Plunker http://plnkr.co/pc8kgj :

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

不需要像下面这样遍历 DOM 就可以得到 头儿左边:

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) };
}

document-offset (第三方剧本)很有趣,它似乎利用了这里其他答案的方法。

例如:

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

如果您不介意使用 jQuery,那么可以使用 offset()函数。如果您想了解更多关于这个函数的信息,请参考 文件

对于那些希望获取元素相对于文档的各个位置的 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')

我发现下面的方法是最可靠的,当处理边缘情况,绊倒了偏移顶部/偏移左。

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