滚动时,JavaScript getBoundingClientRect()会更改

我想要一个元素的Y坐标和Y值= 0之间的确切距离,我认为这是文档的顶部。

myElement.getBoundingClientRect().top;

但getBoundingClientRect()的值在滚动时似乎发生了变化。 我怎样才能得到myElement和Y坐标= 0(文档的顶部)之间的真正距离?


这是因为getBoundingClientRect()相对于window (只有页面的当前可见部分)而不是document (整个页面)获取值。
因此,它在计算其值时也需要考虑滚动
基本上, document = window + scroll

因此,为了获得myElement和Y坐标= 0(文档的顶部)之间的距离,您还需要添加垂直滚动的值:

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

要避免的错误是:

  • 由于Chrome Mobile 43的scrollY / pageYOffset值不正确(特别是键盘显示和滚动时),因此在Android Chrome浏览器中滚动。

  • 在Microsoft IE或Edge中缩放会导致scrollY / pageYOffset值错误。

  • 一些(过时的)浏览器没有高度/宽度,例如IE8

  • 编辑:上面的代码可以简化很多只是使用document.body.getBoundingClientRect()而不是添加一个div - 我还没有尝试过,所以我离开我的答案,因为它站立。 此外身体需要margin:0 (reset.css通常这样做)。 这个答案简化了代码,同时还避免了jQuery.offset()中的错误!

    编辑2:Chrome 61引入了window.visualViewport ,为实际视口提供正确的值,这可能是解决问题的另一种方式; 但要注意的是,如果Settings -> Accessability -> Force enable zoom勾选(方向更改错误,焦点输入,绝对位置弹出窗口比视口更宽),Android Chrome 66仍然有问题。

    链接地址: http://www.djcxy.com/p/15611.html

    上一篇: JavaScript getBoundingClientRect() changes while scrolling

    下一篇: How to catch x and y position and reposition exactly in MVC4?