74

要素の Y 座標と Y 値 = 0 の間の正確な距離が必要です。これをドキュメントの上部と見なします。

myElement.getBoundingClientRect().top;

しかし、スクロール中に getBoundingClientRect() の値が変わるようです。myElement と Y 座標 = 0 (ドキュメントの上部) の間の実際の距離を取得するにはどうすればよいですか?

4

2 に答える 2

32

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

回避すべきバグは次のとおりです。

編集: 上記のコードはdocument.body.getBoundingClientRect()、div を追加する代わりに使用するだけで大​​幅に簡略化できます。ただし、試したことはないので、回答はそのままにしておきます。本体も必要margin:0です (reset.css は通常これを行います)。この回答により、jQuery.offset() のバグを回避しながら、コードが大幅に簡素化されます。

編集 2:実際のビューポートに正しい値を与えるために導入された Chrome 61は、おそらく問題を修正する別の方法です。window.visualViewportただし、Android Chrome 66 にチェックが入っていてもまだバグがあることに注意してくださいSettings -> Accessability -> Force enable zoom(向きの変更、フォーカスされた入力、絶対にビューポートより広い位置にポップアップを配置するなどのバグ)。

于 2015-09-17T06:29:38.663 に答える