刷新页面到底部时,Chrome浏览器会出现垂直跳跃问题

8
我注意到在使用Chrome开发网站时出现了以下行为:当我在页面被完全向下滚动时刷新页面,我可以观察到一个垂直的跳跃。
请参见以下 Bootply
要重现,请打开全屏预览(右侧的显示器图标),并尝试以下操作:
  1. 刷新页面(确认表单重新提交)-> 不会跳跃
  2. 滚动到中间,刷新(确认表单重新提交)-> 不会跳跃
  3. 滚动到底部,刷新(确认表单重新提交)-> 垂直跳跃
事实上,这个JavaScript引起了这个跳跃,它试图在页面包含带有.align-center类的图像时维护垂直节奏。
$(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中尝试时,我没有观察到任何跳跃。
请问您有任何想法吗?
编辑:我在Chrome的错误跟踪器上开了一个bug

我不知道我的Chrome安装是否存在某种问题,但即使我完全删除JS并添加* { margin: 0 !important; padding: 0 !important; height: auto!important; min-height: 0 !important; },我仍然看到跳跃。 - Jonas Grumann
我认为你试图将图像容器高度转换为20的倍数(行高)。如果是这样,那么你的计算是错误的。300是20的倍数,在这种情况下不需要填充。 - Salman A
一个可能的解决方法是附加到onscroll事件,并确保页面始终至少在非常底部上方一个像素。 - Dag Sondre Hansen
2个回答

2
首先,我必须让您失望,因为我不是Chrome开发人员或其他官方来源。但我花了一些时间研究这个问题,并想分享一下我的发现。你知道的,为了后人留个记录。
正如你可能已经做过的那样,在代码中添加了一些alert并尝试观察发生了什么。在我看来,似乎视口被渲染,Javascript运行,填充被应用,整个内容被推下去,然后Chrome意识到并修复视口高度以适应额外的填充。对我来说,这看起来像一个诚实的渲染错误。
话虽如此,我确实找到了一些解决方法,至少在我的测试中有效。我不知道这是否适用于您的环境,但也许它有助于进一步诊断渲染问题。
简单地将额外的空间添加到边距而不是填充中就可以解决这个问题。
if (bottom != 0)
{
    bottom += parseInt($(this).css('padding-bottom'), 10);
    $(this).css('margin-bottom', bottom);
}

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

边距不够用。边距是可折叠的,所以需要填充(padding)。 - Gregory Pakosz
这个问题可能可以通过一些透明的 border-bottom 数学计算来解决,但我理解你的观点。这不是一个好的解决方案。 - oelna
感谢您在这里投入时间,欢迎来到SO。我已经在提交的错误报告中提到了这个问题,我们将等待Chrome开发人员的回复。 - Gregory Pakosz
哇,你们太棒了!我会好好利用这个声誉的。我也非常想看看这个错误报告会有什么结果。 - oelna

1

我没有完整的答案,但是关于Chrome我有一些观察:

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

你的代码似乎在文档准备就绪事件中向图像添加了20像素的填充。因此,这里是结果:

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

浏览器将滚动到与刷新之前相同的内容。增加的正文高度不会影响滚动位置,除了滚动条改变其高度。

滚动到底部+刷新:

浏览器尝试在可能的情况下将正文对齐到底部。它似乎这样做两次+。当内容可用时,正文会滚动到底部。然后在文档准备就绪时,正文的高度增加了20像素,这会激活“向下滚动”按钮。在页面加载时,浏览器再次将正文与底部对齐,将所有内容向下推20像素,从而创建“垂直跳跃”行为。

+ 为了测试,我添加了 $(window).scroll(function() { console.log(arguments); })。滚动事件触发了两次:文档加载后和窗口加载后。
总之:
如果在页面刷新前页面底部对齐,则 Chrome 似乎会将 body 与页面底部对齐。它会在页面加载之前和之后过早地这样做,从而导致跳动效果。
Firefox 似乎遵循相同的步骤。但是,Firefox 似乎聪明地处理到达底部的情况。由于 body 与底部对齐,它会在视口上方的区域中进行布局更改(由 padding 触发);增加滚动条的高度但不滚动。

你介意我把悬赏给oelna吗?你们两个都投入了时间,我很感激。我会点赞你们的回答。但是我想用悬赏作为欢迎的赞扬。你认为呢? - Gregory Pakosz
我已经在我编辑过的问题中打开了一个错误报告,我们将看看Chrome开发人员对此有何想法。 - Gregory Pakosz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接