要素の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
編集:上記のコードは、divを追加する代わりにdocument.body.getBoundingClientRect()
を使用するだけで大幅に簡素化できます。まだ試していませんので、答えをそのままにしておきます。また、本文にはmargin:0
が必要です(通常、reset.cssがこれを行います)。 この回答 jQuery.offset()のバグを回避しながら、コードを大幅に簡素化します!
編集2: Chrome 61ではwindow.visualViewport
を導入して、実際のビューポートに正しい値を与えました。これはおそらく問題を修正する別の方法です。ただし、Android Chrome 66は、Settings -> Accessability -> Force enable zoom
にチェックマークが付いている場合はバグが残ることに注意してください(ビューポートよりも広い位置にポップアップが配置され、方向が変わるバグ)。