jjzjj

javascript - jQuery offset() 被 body 位置打破 :relative combined with element margin

coder 2025-01-02 原文

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

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

  • 正文是position:relative
  • 页面顶部有H1
  • H1 的边距似乎在计算主体 0,0 的位置发生变化 - 即使主体上的背景一直延伸到边缘,并且它的 offsetTop 属性报告为 0
  • 在 body 上设置边框解决了这个问题 - 看起来很奇怪但在浏览器之间是一致的吗? (不是可行的解决方案)
  • 移除 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
  })
});

最佳答案

I don't think this is a bug with jQuery - it seems to be down to a legitimate relationship between the H1 margin and the body element?

是的:正文和 h1 的边距是 collapsing ,因此不仅 h1 会向下移动其默认边距,body 也会向下移动。这就是您能够进行这些观察的原因:

  • Setting a border on the body solves the problem - seems strange behaviour but is consistent across browsers? (not a viable solution)
  • Removing the H1 margins solves the problem (not a viable solution)

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

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

  1. #existing 在正常流中被 h1 向下推作为其后续兄弟。这增加了它与视口(viewport)的偏移量(在您的 CodePen 测试用例中,它位于预览 Pane 的顶部),导致其 offsetTop 更大。

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

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

总结:由于边距崩溃,浏览器最终不得不考虑 h1 和 body 的向下移动。 h1 影响 #existing,进而影响它的 offsetTop,而 body 在相对定位时影响 #overlay。因此,这种转变效应是双重的。

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

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

Updated example

请注意,使用 $(document.body) 代替上面的 $("h1") 是行不通的。这是因为 margin collapse 纯粹是一种渲染效果,在给它自己的 margin 之前不会真正影响 body 的偏移量(换句话说,body margins 仍然计算为零,所以 DOM 仍然不明智)。


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

  • The margin from the H1 seems to change where the body 0,0 is calculated from - even though the background on the body extends all the way to the edge, and it's offsetTop property reports 0

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

至于 body 背景:虽然它看起来一直延伸到边缘,但这个扩展背景实际上并不属于 body - 它从 body 传播到根元素 (html),因此属于根元素 (html) 和视口(viewport)。参见 this answer寻求解释。

哦还有这个:

This isn't a bug because the behaviour is consistent across FF, Chrome, IE9 and Safari on Win7.

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

关于javascript - jQuery offset() 被 body 位置打破 :relative combined with element margin,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13384660/

有关javascript - jQuery offset() 被 body 位置打破 :relative combined with element margin的更多相关文章

  1. ruby - 正则表达式在哪个位置失败? - 2

    我需要一个非常简单的字符串验证器来显示第一个符号与所需格式不对应的位置。我想使用正则表达式,但在这种情况下,我必须找到与表达式相对应的字符串停止的位置,但我找不到可以做到这一点的方法。(这一定是一种相当简单的方法……也许没有?)例如,如果我有正则表达式:/^Q+E+R+$/带字符串:"QQQQEEE2ER"期望的结果应该是7 最佳答案 一个想法:你可以做的是标记你的模式并用可选的嵌套捕获组编写它:^(Q+(E+(R+($)?)?)?)?然后你只需要计算你获得的捕获组的数量就可以知道正则表达式引擎在模式中停止的位置,你可以确定匹配结束

  2. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  3. ruby - 下载位置 Selenium-webdriver Cucumber Chrome - 2

    我将Cucumber与Ruby结合使用。通过Selenium-Webdriver在Chrome中运行测试时,我想将下载位置更改为测试文件夹而不是用户下载文件夹。我当前的chrome驱动程序是这样设置的:Capybara.default_driver=:seleniumCapybara.register_driver:seleniumdo|app|Capybara::Selenium::Driver.new(app,:browser=>:chrome,desired_capabilities:{'chromeOptions'=>{'args'=>%w{window-size=1920,1

  4. ruby - Heroku production.log 文件位置 - 2

    我想在heroku.com上查看我的应用程序日志的内容,所以我关注了thisexcellentadvice并拥有我所有的日志内容。但是我现在很想知道我的日志文件实际在哪里,因为“log/production.log”似乎是空的:C:\>herokuconsoleRubyconsoleforajpbrevx.heroku.com>>files=Dir.glob("*")=>["public","tmp","spec","Rakefile","doc","config.ru","app","config","lib","README","Gemfile.lock","vendor","sc

  5. ruby - 在 Ruby 中查找多个正则表达式匹配的模式和位置 - 2

    这应该是一个简单的问题,但我找不到任何相关信息。给定一个Ruby中的正则表达式,对于每个匹配项,我需要检索匹配的模式$1、$2,但我还需要匹配位置。我知道=~运算符为我提供了第一个匹配项的位置,而string.scan(/regex/)为我提供了所有匹配模式。如果可能,我需要在同一步骤中获得两个结果。 最佳答案 MatchDatastring.scan(regex)do$1#Patternatfirstposition$2#Patternatsecondposition$~.offset(1)#Startingandendingpo

  6. ruby-on-rails - 尝试打开 .gitignore 以在文本编辑器中对其进行编辑,但在 OS X Mountain Lion 上找不到文件位置 - 2

    我使用“newapp_name”创建了一个新的Rails应用程序,我正在尝试编辑.gitignore文件,但在我的应用程序文件夹中找不到它。我在哪里可以找到它?我安装了Git。 最佳答案 .gitignore位于项目的root中,而不是app子目录中。首先打开终端并进入您的目录。您需要使用ls-a来显示stash文件。然后使用打开.gitignore 关于ruby-on-rails-尝试打开.gitignore以在文本编辑器中对其进行编辑,但在OSXMountainLion上找不到文件位

  7. ruby-on-rails - 在 Rails 中存储(结构化)配置数据的位置 - 2

    对于我正在编写的Rails3应用程序,我正在考虑从本地文件系统上的XML、YAML或JSON文件中读取一些配置数据。重点是:我应该把这些文件放在哪里?Rails应用程序中是否有用于存储此类内容的默认位置?附带说明一下,我的应用程序部署在Heroku上。 最佳答案 我经常做的是:如果文件是通用配置文件:我在目录/config中创建一个YAML文件,每个环境有一个上层key如果我为每个环境(大项目)创建一个文件:我为每个环境创建一个YAML并将它们存储在/config/environments/然后我在加载YAML的地方创建了一个初始化

  8. Ruby:数组中的下一个/上一个值,循环数组,数组位置 - 2

    假设我有一个没有特定顺序的随机数数组。假设这些是参加马拉松比赛的人的ID#,他们按照完成的顺序添加到数组中,例如:race1=[8,102,67,58,91,16,27]race2=[51,31,7,15,99,58,22]这是一个简化且有些做作的示例,但我认为它传达了基本思想。现在有几个问题:首先,我如何获得特定条目之前和之后的ID?假设我正在查看运行者58,我想知道谁在他之前和之后完成了比赛。race1,runner58:previousfinisher=67,nextfinisher=91race2,runner58:previousfinisher=99,nextfinishe

  9. ruby - 在 Mechanize 中使用 JavaScript 单击链接 - 2

    我有这个:AccountSummary我想单击该链接,但在使用link_to时出现错误。我试过:bot.click(page.link_with(:href=>/menu_home/))bot.click(page.link_with(:class=>'top_level_active'))bot.click(page.link_with(:href=>/AccountSummary/))我得到的错误是:NoMethodError:nil:NilClass的未定义方法“[]” 最佳答案 那是一个javascript链接。Mechan

  10. ruby-on-rails - 在 Rails 中向 Integer 类添加方法的最佳位置在哪里? - 2

    在Rails中向整数类添加方法的最佳位置在哪里?我想添加一个to_meters和to_miles方法。 最佳答案 如果您决心使用数字(或整数等)类来进行单位转换,那么至少要在逻辑上做到这一点,并具有一些实际值(value)。首先,创建一个Unit类,用于存储单位类型(米、英尺、肘等)和创建时的值。然后向Numeric添加一堆方法,这些方法对应于单元可以具有的有效值:这些方法将返回一个单元对象,其类型记录为方法名称。Unit类将支持一组to_*方法,这些方法将转换为具有相应单位值的另一种单位类型。这样,您可以执行以下命令:>>x=47

随机推荐