【问题标题】:Chrome vertical jump when refreshing page scrolled to bottom刷新页面滚动到底部时Chrome垂直跳转
【发布时间】:2014-06-27 14:53:32
【问题描述】:

在使用 Chrome 开发网站时注意到以下行为:当我在页面完全滚动到底部时刷新页面时,我可以观察到垂直跳跃。

请参阅以下Bootply

要重现,请打开全屏预览(右侧的监视器图标),然后尝试以下操作:

  1. 刷新页面(确认表单重新提交)-->不跳转
  2. 滚动到中间,刷新(确认表单重新提交)-->不跳转
  3. 滚动到最底部,刷新(确认表单重新提交)-->垂直跳转

跳转实际上是由于当页面包含.align-center类的图形时,这个试图保持垂直节奏的Javascript引起的:

$(document).ready(function() {
  $(window).resize(function() {
    var baseline = parseInt($('body').css('line-height'), 10)
    $('.align-center').each(function() {
      var height = $(this).outerHeight();
      console.log(height)
      var bottom = baseline - (height % baseline);

      if (bottom != 0)
      {
        bottom += parseInt($(this).css('padding-bottom'), 10)
        $(this).css('padding-bottom', bottom);
      }
    });
  }).trigger("resize");
});

当然,删除此 Javascript 也会删除观察到的垂直跳跃。 我不明白的是,当 DOM 准备好时会应用填充,因此它不应该导致可见的垂直跳跃。我认为跳转与当页面滚动到最底部时 Chrome 处理视口的方式有关,但我真的不知道如何确认/确认这一点。

在 Firefox 或 Safari 中尝试此操作时,我没有观察到任何跳跃。

有什么想法吗?


编辑:I opened a bug on Chrome's bug tracker

【问题讨论】:

  • 我不知道我的 chrome 安装是否存在某种问题,但即使我完全删除 js 并添加 * { margin: 0 !important; 也会看到跳转填充:0!重要;高度:自动!重要;最小高度:0!重要; }
  • 我认为您正在尝试将图像容器高度转换为 20 的倍数(行高)。如果这是正确的,那么你的计算是错误的。 300 是 20 的倍数,在这种情况下不需要填充。
  • 一种可能的解决方法是附加到 onscroll 事件并确保页面始终位于最底部上方至少一个像素。

标签: google-chrome scroll padding vertical-rhythm


【解决方案1】:

首先,我不得不让你失望,因为我不是 Chrome 开发者或其他官方来源。但我确实在这个问题上花了一些时间,并认为我会分享我的发现。你知道,为了后代。

您可能已经知道了,我在代码中添加了几个alerts 并试图观察到底发生了什么。在我看来,视口被渲染,Javascript 运行,填充被应用,整个其余内容被向下推,然后 Chrome 实现并修复视口高度以适应额外的填充。对我来说,这看起来像是一个诚实的渲染错误。

也就是说,至少在我的测试中,我确实找到了一些可以解决这个问题的方法。我不知道这是否适用于您的环境,但也许它有助于进一步诊断渲染问题。

只需将额外的空间添加到边距,而不是填充,为我做了。

if (bottom != 0)
{
    bottom += parseInt($(this).css('padding-bottom'), 10);
    $(this).css('margin-bottom', bottom);
}

也许其他人可以提出一个实际的解释。我很想知道究竟是什么导致了这种令人不安的行为。

【讨论】:

  • margin 没有削减它。边距是可折叠的,这就是需要填充的原因
  • 这可能可以通过一些透明的border-bottom 数学来解决,但我明白你的意思。这不是一个好的解决方案。
  • 感谢您在这方面投入时间,欢迎来到 SO。我们将在我打开的错误报告中看到 Chrome 开发人员对此的看法(请参阅编辑后的问题)。
  • 哇,你们太棒了!我会看到我很好地利用了声誉。我也很想看看错误报告会出现什么。
【解决方案2】:

我没有完整的答案,但对 Chrome 有一些看法:

  1. 浏览器可以在文档就绪事件之前开始绘制文档
  2. 浏览器可以在文档就绪事件之前显示垂直滚动条
  3. 浏览器可以在文档就绪事件之前滚动到以前可见的内容
  4. 浏览器可以在窗口加载后滚动到以前可见的内容

您的代码似乎在文档就绪事件中为图形添加了 20 像素的填充。所以后果如下:

滚动到顶部或中间+刷新:

浏览器将相同的内容滚动到刷新前可见的视图中。 body 高度的增加不会影响滚动位置,只是滚动条改变了它的高度。

滚动到底部 + 刷新:

浏览器会尽可能将正文与底部对齐。似乎这样做两次+。当内容可用时,正文会一直滚动到底部。然后在文档就绪时将 20px 添加到正文高度,这会激活“向下滚动”按钮。在页面加载时,浏览器再次将主体与底部对齐,将所有内容向下推 20 像素,从而创建“垂直跳转”行为。

+ 为了测试,我添加了$(window).scroll(function() { console.log(arguments); })。滚动事件触发了两次:文档读取后和窗口加载后。

总结:

如果在页面刷新之前这样,Chrome 似乎会将正文与页面底部对齐。它会在页面加载后过早地执行此操作,从而导致跳转效果。

Firefox 似乎遵循相同的步骤。但是,Firefox 似乎智能地处理滚动到底部大小写。由于 body 与底部对齐,它使 viewport 上方区域的布局发生变化(由 padding 触发);增加滚动条的高度但不滚动。

【讨论】:

  • 你同意我给 oelna 赏金吗?你们都为此投入了时间,我对此表示感谢。我会赞成你各自的答案。但我想用赏金作为欢迎的大拇指。你怎么看?
  • 我们将在我打开的错误报告中了解 Chrome 开发人员的想法(请参阅已编辑的问题)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-24
  • 1970-01-01
  • 1970-01-01
  • 2014-06-10
  • 1970-01-01
相关资源
最近更新 更多