6

这不是错误,因为在 Win7 上,FF、Chrome、IE9 和 Safari 的行为是一致的。

我正在开发的应用程序是主机页面的第 3 方,因此 CSS 是不可变的。脚本尝试将新 div 与现有元素对齐。

  • 身体位置:相对
  • 页面顶部有一个H1
  • H1 的边距似乎改变了计算主体 0,0 的位置 - 即使主体上的背景一直延伸到边缘,并且它的 offsetTop 属性报告为 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 的边距正在collapsing,所以不仅 h1 被其默认边距向下移动,body 也是如此。这就是为什么你能够做出这些观察:

  • 在正文上设置边框可以解决问题 - 看起来很奇怪,但在浏览器中是一致的?(不是一个可行的解决方案)
  • 删除 H1 边距可以解决问题(不是可行的解决方案)

无论如何,通过将 body 设置为position: relative,您就是在告诉#overlay以 body 的顶部偏移作为原点来绝对定位自己。然后,您的脚本将其相对于#existing. 它的值offsetTop是相对于视口的,它是根据这个盒子的位置来计算的……它本身是相对于h1的,因为它在正常流程中直接跟随h1。

因为 h1 和 body 元素的边距正在折叠,所以它们具有相同的渲染边距。然后发生的事情是双重的:

  1. #existing在正常流程中被 h1 作为其下一个兄弟下推。这会增加它与视口的偏移量(在您的 CodePen 测试用例中,它是预览窗格的顶部),从而导致它offsetTop更大。

  2. 当 body 设置为 时position: relative#overlay最终会定位到其原点设置为 body 的原点,由于与 h1 的边距折叠,它本身也被推下。这会增加其原点的顶部偏移量,如果您没有定位主体,则不会发生这种情况,因为那样会#overlay使用视口的原点,它永远不会移动。

#existing到视口顶部的距离被添加到#overlay从其原点(即身体)的偏移量上,从而产生这种效果。

总结:由于边距崩溃,浏览器最终不得不考虑 h1 和 body 的向下移动。h1#existing反过来影响它的,而当你相对定位它时offsetTop,body 会影响它。#overlay因此,转移效应出现了双重效果。

作为一种快速解决方法,您可以从偏移量中减去 h1 边距,以达到偏移量#existing的目的#overlay

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

更新示例

请注意,使用$(document.body)而不是$("h1")上面将不起作用。这是因为边距折叠纯粹是一种渲染效果,并且在您给它自己的边距之前实际上不会影响主体的偏移量(换句话说,主体边距仍然计算为零,因此 DOM 仍然不明智)。


与手头的问题没有直接关系,但无论如何都值得解决:

  • H1 的边距似乎改变了计算主体 0,0 的位置 - 即使主体上的背景一直延伸到边缘,并且它的 offsetTop 属性报告为 0

上面已经讨论了这一点的第一部分和最后一部分。

至于主体背景:虽然它看起来一直延伸到边缘,但这个延伸的背景实际上并不属于主体——它从主体传播到根元素 (html) 和视口,因此属于根元素 (html) 和视口。请参阅此答案以获取解释。

哦,还有这个:

这不是错误,因为在 Win7 上,FF、Chrome、IE9 和 Safari 的行为是一致的。

让我微笑。因为这一次,有人说得对。

于 2012-11-14T22:17:21.040 回答
0

如果您将位置更改为overlayfrom absolutefixed则它可以正常工作。这意味着偏移值是正确的。我认为这与overlay元素相对于其前一个元素的位置有关。

于 2012-11-14T18:22:56.400 回答