[英]JavaScript getBoundingClientRect() changes while scrolling
I want to have the exact distance between the Y-coordinate of an element an the Y-value=0, which I consider as the top of the document. 我想要一个元素的Y坐标和Y值= 0之间的确切距离,我认为它是文档的顶部。
myElement.getBoundingClientRect().top;
But the value of getBoundingClientRect() seems to change while scrolling. 但是getBoundingClientRect()的值似乎在滚动时发生了变化。 How can I get the real distance between myElement and the Y-coordinate=0 (top of document)?
如何获得myElement和Y坐标= 0(文档顶部)之间的实际距离?
It is because getBoundingClientRect()
gets values with respect to the window
(only the current visible portion of the page), not the document
(whole page). 这是因为
getBoundingClientRect()
获取相对于window
值(仅页面的当前可见部分),而不是document
(整个页面)。
Hence, it also takes scrolling into account when calculating its values 因此,在计算其值时也需要考虑滚动
Basically, document = window + scroll
基本上,
document = window + scroll
So, to get the distance between myElement and the Y-coordinate=0 (top of document), you would have add the value of vertical-scroll also: 因此,要获得myElement和Y坐标= 0(文档顶部)之间的距离,您还可以添加垂直滚动的值:
myElement.getBoundingClientRect().top + window.scrollY;
Source: https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect 资料来源: https : //developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect
getBoundingClientRect needs a bit more care to avoid bugs in scrollY/pageYOffset: 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
};
}
The bugs to avoid are: 要避免的错误是:
scrolling in Android Chrome since Chrome Mobile 43 has wrong values for scrollY/pageYOffset (especially when the keyboard is showing and you scroll). 在Android Chrome中滚动,因为Chrome Mobile 43的scrollY / pageYOffset 值不正确(特别是当键盘显示并滚动时)。
Pinch-zoom in Microsoft IE or Edge causes wrong values for scrollY/pageYOffset. 在Microsoft IE或Edge中进行缩放会导致scrollY / pageYOffset的值不正确。
Some (obsolete) browsers don't have a height/width eg IE8 一些(过时的)浏览器没有高度/宽度,例如IE8
Edit: The above code can be simplified a lot by just using document.body.getBoundingClientRect()
instead of adding a div - I haven't tried it though so I am leaving my answer as it stands. 编辑:上面的代码可以简单地通过使用
document.body.getBoundingClientRect()
而不是添加div来简化 - 我没有尝试过,所以我现在就离开我的答案了。 Also the body needs margin:0
(reset.css usually does this). 身体也需要
margin:0
(reset.css通常这样做)。 This answer simplifies the code down a lot, while still avoiding the bugs in jQuery.offset()! 这个答案简化了代码,同时仍然避免了jQuery.offset()中的错误!
Edit 2: Chrome 61 introduced window.visualViewport
to give correct values for the actual viewport which is probably another way to fix issues; 编辑2: Chrome 61引入了
window.visualViewport
,为实际视口提供了正确的值,这可能是解决问题的另一种方法; but beware that Android Chrome 66 was still buggy if Settings -> Accessability -> Force enable zoom
was ticked (bugs with orientation change, focused inputs, absolutely positioned popup wider than viewport). 但请注意,如果
Settings -> Accessability -> Force enable zoom
,则Android Chrome 66仍然存在错误(方向更改错误,聚焦输入,绝对定位的弹出窗口比视口更宽)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.