簡體   English   中英

滾動時JavaScript getBoundingClientRect()會發生變化

[英]JavaScript getBoundingClientRect() changes while scrolling

我想要一個元素的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
    };
}

要避免的錯誤是:

  • 在Android Chrome中滾動,因為Chrome Mobile 43的scrollY / pageYOffset 不正確(特別是當鍵盤顯示並滾動時)。

  • 在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仍然存在錯誤(方向更改錯誤,聚焦輸入,絕對定位的彈出窗口比視口更寬)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM