我想要元素的 Y 坐标与 Y 值 = 0 之间的确切距离,我认为它是文档的顶部。
myElement.getBoundingClientRect().top;
但是 getBoundingClientRect() 的值似乎在滚动时发生了变化。如何获得 myElement 和 Y 坐标 = 0(文档顶部)之间的实际距离?
我想要元素的 Y 坐标与 Y 值 = 0 之间的确切距离,我认为它是文档的顶部。
myElement.getBoundingClientRect().top;
但是 getBoundingClientRect() 的值似乎在滚动时发生了变化。如何获得 myElement 和 Y 坐标 = 0(文档顶部)之间的实际距离?
这是因为getBoundingClientRect()
获取相对于window
(仅页面的当前可见部分)而不是document
(整个页面)的值。
因此,它在计算其值时也会考虑滚动
基本上, document = window + scroll
因此,要获得 myElement 和 Y-coordinate=0(文档顶部)之间的距离,您还需要添加 vertical-scroll 的值:
myElement.getBoundingClientRect().top + window.scrollY;
来源:https ://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect
getBoundingClientRect 需要更加小心以避免scrollY/pageYOffset 中的错误:
function absolutePosition(el) {
var
found,
left = 0,
top = 0,
width = 0,
height = 0,
offsetBase = absolutePosition.offsetBase;
if (!offsetBase && document.body) {
offsetBase = absolutePosition.offsetBase = document.createElement('div');
offsetBase.style.cssText = 'position:absolute;left:0;top:0';
document.body.appendChild(offsetBase);
}
if (el && el.ownerDocument === document && 'getBoundingClientRect' in el && offsetBase) {
var boundingRect = el.getBoundingClientRect();
var baseRect = offsetBase.getBoundingClientRect();
found = true;
left = boundingRect.left - baseRect.left;
top = boundingRect.top - baseRect.top;
width = boundingRect.right - boundingRect.left;
height = boundingRect.bottom - boundingRect.top;
}
return {
found: found,
left: left,
top: top,
width: width,
height: height,
right: left + width,
bottom: top + height
};
}
要避免的错误是:
在 Android Chrome 中滚动,因为 Chrome Mobile 43的 scrollY/pageYOffset值错误(尤其是当键盘显示并且您滚动时)。
Microsoft IE 或 Edge 中的双指缩放会导致scrollY/pageYOffset 的值错误。
一些(过时的)浏览器没有高度/宽度,例如 IE8
编辑:上面的代码可以通过使用而不是添加一个 div 来简化很多document.body.getBoundingClientRect()
- 我还没有尝试过,所以我留下我的答案。身体也需要margin:0
(reset.css 通常这样做)。这个答案大大简化了代码,同时仍然避免了 jQuery.offset() 中的错误!
编辑 2:引入 Chrome 61window.visualViewport
为实际视口提供正确的值,这可能是解决问题的另一种方法;但请注意,如果Settings -> Accessability -> Force enable zoom
勾选,Android Chrome 66 仍然存在错误(方向更改、焦点输入、绝对定位的弹出窗口比视口更宽的错误)。