6

Win7 の FF、Chrome、IE9、Safari で動作が一貫しているため、これはバグではありません。

私が取り組んでいるアプリは、ホスト ページのサード パーティであるため、CSS は不変です。スクリプトは、新しい div を既存の要素に合わせようとします。

  • 本体は位置:相対
  • ページの上部に H1 があります
  • H1 からのマージンは、ボディ 0,0 が計算される場所によって変化するように見えます。
  • 本文に境界線を設定すると問題が解決します - 奇妙な動作に見えますが、ブラウザ間で一貫していますか? (実行可能な解決策ではありません)
  • H1マージンを削除すると問題が解決します(実行可能な解決策ではありません)

ここの例では、JS は各ケースを複製するためにコメントされています:
http://codepen.io/anon/pen/EGvlb

これは jQuery のバグではないと思います。H1 マージンと body 要素の間の正当な関係にあるようです。

$(function(){

  /* Setting body to position:relative breaks offset()
     because H1 margin moves body down */
  $(document.body).css({position: "relative"});

  /* Strange: putting a border on body fixes things? */
  //$(document.body).css({border: "1px solid #000"});

  /* Removing H1 margin removes problem */
  //$("h1").css({margin: 0});

  $("#overlay").css({
      left: $("#existing").offset().left,
      top: $("#existing").offset().top
  })
});
4

2 に答える 2

4

これは jQuery のバグではないと思います。H1 マージンと body 要素の間の正当な関係にあるようです。

ええ: body と h1 のマージンが崩壊しているため、h1 がデフォルトのマージンだけ下にシフトされるだけでなく、body も下にシフトされます。これが、これらの観察を行うことができた理由です。

  • 本文に境界線を設定すると問題が解決します - 奇妙な動作に見えますが、ブラウザ間で一貫していますか? (実行可能な解決策ではありません)
  • H1マージンを削除すると問題が解決します(実行可能な解決策ではありません)

とにかく、本体を に設定することで、本体の上部オフセットを原点として絶対に配置するようにposition: relative指示しています。#overlay次に、スクリプトは のオフセットに対して相対的に移動し#existingます。その値はoffsetTop、このボックスの位置に基づいて計算されるビューポートに相対的です...通常のフローでは h1 に直接続くため、h1 に相対的です。

h1 要素と body 要素のマージンが折りたたまれているため、レンダリングされたマージンは同じです。その場合、次の 2 つのことが起こります。

  1. #existing通常のフローでは、h1 によって次の兄弟として押し下げられます。これにより、ビューポートからのオフセットが増加し (CodePen テスト ケースでは、プレビュー ペインの上部)、結果としてoffsetTop大きくなります。

  2. ボディが に設定されている場合、 はボディの原点に設定された原点で配置され、ボディ自体も h1 の余白position: relative#overlay折りたたまれているために押し下げられます。これにより、原点の上部オフセットが増加しますが、ボディを配置していない場合は発生しません#overlay。これは、ビューポートの原点が代わりに使用され、決して移動しないためです。

ビューポートの上部からの距離が、本体である原点から#existingのオフセットに追加され、この効果が得られます。#overlay

要約すると、マージンの崩壊により、ブラウザーは h1 と body の両方で下向きのシフトを考慮する必要があります。h1 は に影響#existingを与え、次にそのoffsetTopに影響を与えますが、体#overlayは相対的に配置すると影響を与えます。したがって、シフト効果は 2 重に現れます。

#existing簡単な回避策として、オフセットの目的で のオフセットから h1 マージンを差し引くことができます#overlay

  $("#overlay").css({
      left: $("#existing").offset().left - $("h1").offset().left,
      top: $("#existing").offset().top - $("h1").offset().top
  })

更新された例

$(document.body)上記の代わりに使用すると機能しないことに注意してください$("h1")。これは、マージンの縮小は純粋にレンダリング効果であり、独自のマージンを指定するまで実際にはボディのオフセットに影響を与えないためです (つまり、ボディのマージンはまだゼロに計算されているため、DOM は賢明ではありません)。


当面の問題とは直接関係ありませんが、とにかく対処する価値があります。

  • H1 からのマージンは、ボディ 0,0 が計算される場所によって変化するように見えます。

この点の最初と最後の部分は上で説明されています。

本体の背景については、端まで伸びているように見えますが、この拡張された背景は実際には本体に属していません。本体からルート要素 (html) とビューポートに伝播され、これらに属しています。説明については、この回答を参照してください。

ああ、これ:

Win7 の FF、Chrome、IE9、Safari で動作が一貫しているため、これはバグではありません。

私を笑顔にしました。一度だけ、誰かがそれを言うのは正しいからです。

于 2012-11-14T22:17:21.040 に答える
0

の位置をoverlayからabsoluteに変更すると、正常fixedに機能します。これは、オフセット値が正しいことを意味します。overlay前の要素に対する要素の位置に関係していると思います。

于 2012-11-14T18:22:56.400 に答える