私は次のDOM構造を持っています
<body>
<div>
<table>
<outerElement>
<innerElement />
</outerElement>
<table>
</div>
</body>
DIVのオーバーフローは自動に設定されているため、テーブルが大きくなると、DIV内でスクロールします。
このシナリオでは、なぜtable.offsetParent
は、両方のtable.parentNode
とparentElement
はDivを返しますか?
ウィンドウ内のinnerElement
の現在の位置を計算する必要があるので、そこからすべての親要素をトラバースして、offsetTop
とoffsetLeft
の値を収集します。 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;
}
ここで、getStyle
は、この場合は位置スタイルを取得するカスタム関数です。
offsetParent
に近づかないでください。正しく機能するように、多くのハックとチェックを追加する必要があります。
代わりに getBoundingClientRect を使用してみてください。
offsetParent
は、position:relative
またはposition:absolute
またはページの本文を持つ最も近い親です。 parentNode
は、position
に関係なく、直接の親です。
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
}
}
_
注:document.body.getBoundingClientRect()
は、状況によってはFirefoxでtop
に予期しない値を返す場合があります。したがって、ウィンドウのスクロール位置はより堅牢になります。
GetBoundingClientRect()をまだサポートしていないクライアントの場合でも、offetParentsをウォークし、すべての_overflow: scroll
_(または自動)親が_position: relative
_を持つように注意する必要があります。