16

次のDOM構造があります

<body>
    <div>
       <table>
          <outerElement>
              <innerElement />  
          </outerElement>
       <table>
    </div>
</body>

DIV のオーバーフローは auto に設定されているため、テーブルが大きくなると、DIV 内でスクロールします。

このシナリオでtable.offsetParentは、ボディを返しながらDivtable.parentNodeを返すのはなぜですか?parentElement

ウィンドウ内の現在の位置を計算する必要があるinnerElementため、そこからすべての親要素をトラバースして、それらの値offsetTopoffsetLeft値を収集します。DIV が正常に機能するまでは、offsetParentそれを直接本文にスキップします。ある時点でスクロールが関係している場合の問題は、上記の例の DIV のように、考慮する必要がscrollTopあります。scrollLeft問題は、使用するoffsetParentと、親の 1 つとして DIV に遭遇しないことです。

アップデート

これはトラバースを行うコードの一部です。

while (oElem && getStyle(oElem, 'position') != 'absolute' && getStyle(oElem, 'position') != 'relative') { 
   curleft += oElem.offsetLeft;
   curtop += oElem.offsetTop;
   oElem = oElem.offsetParent;
}

wheregetStyleは、この場合位置スタイルを取得するカスタム関数です。

4

4 に答える 4

43

offsetParentposition:relativeまたはposition:absoluteページの本文を持つ最も近い親です。parentNodeに関係なく、直接の親ですposition

于 2013-07-31T15:49:25.553 に答える
4

getBoudingClientRect() を使用すると、非常に役立ちます (ヒントをくれた Ally に感謝します!)。

ドキュメントの左上隅に対する相対的な位置がまだ必要な場合は、次のスニペットが役に立ちます。

if (node.getBoundingClientRect) {
    var rect = node.getBoundingClientRect();
    var sx = -(window.scrollX ? window.scrollX : window.pageXOffset);
    var sy = -(window.scrollY ? window.scrollY : window.pageYOffset);

    return {
        x: rect.left - sx,
        y: rect.top - sy
    }
}

注:状況によっては、Firefox でdocument.body.getBoundingClientRect()予期しない値を返す場合があります。topしたがって、ウィンドウのスクロール位置はより堅牢になります。

getBoundingClientRect() をまだサポートしていないクライアントの場合でも、offetParents をウォークし、すべてのoverflow: scroll(または自動) 親がposition: relative.

于 2015-12-02T10:52:42.573 に答える