Safari在页面加载时第一次"聚焦"事件时出现抖动/跳跃(错误?)

37

我目前正在Safari上解决一个非常令人沮丧的错误,但我不知道该向何处求助。

似乎触发focus事件的大多数元素(但不是所有元素,我无法区分其差异)都会导致页面上所有进行过过渡或动画效果的元素向上和向左跳动约2像素。而这只在页面加载后第一次聚焦时发生。

看到这个错误有点烦人,因为它在droplr.com的登录部分中,我完全无法将其简化为JSFiddle的更简单的案例。

如果您拥有/创建帐户并登录,请单击此下拉列表的编辑图标:

enter image description here

您将看到在页面第一次聚焦时出现抖动。以下是在页面上有单个drop并且我在一个问题元素上触发焦点时的时间轴:

enter image description here

当有更多的drops时,情况就变得越来越相同,但似乎最多只有40次绘制。而且分析器没有发现任何恶意行为。只是通过jQuery内部的一次旅行。

如果我不使用translate3dmatix3d对元素进行布局,而是简单地使用topleft,这个错误就会消失。经过数小时的调试,我已经完全无法解决这个问题了。

希望有人看到过类似情况,能够帮忙查看或给出下一步调试的建议。

非常感谢!

更新:Dave Desandro 建议 这是3D加速机制导致的,于是我尝试使用translate进行测试,果然没有出现抖动。但我不知道为什么硬件加速会在focus事件中触发,并且只触发一次。

我已经尝试在页面加载时设置transformZ为0以加快硬件加速,但是没有成功,欢迎提供更多想法。


你的Safari版本是多少?我刚在Safari 5.1.4上检查了一下,看起来没问题。我知道有几个与动画和变换相关的webkit bug,但它们与文本渲染/抗锯齿有关,而不是矩阵位置。 - Kane Cohen
有趣的是,我也在使用5.1.4版本,而且我知道这个问题也出现在5.2上。 - Joshua Cody
你尝试过在这些元素上使用 -webkit-backface-visibility: hidden; 吗?试一试吧。 - frontsideup
不幸的是,隐藏背面可见性也没有帮助。 - Joshua Cody
你说那些抖动的元素是用过渡或动画样式设计的。你是使用 -webkit-transition: all 吗?还是只指定你需要的过渡效果? - codelove
如果您在字体上看到这个问题,也许添加 -webkit-font-smoothing: antialiased; 可以帮助解决。 - Alex K
7个回答

1

我之前遇到过这个问题,但老实说我不记得具体的原因了,以下是我遵循的一些步骤:

检查一下你是否在下一行或反之亦然中为相同元素使用了hide()和show()。 例如: el.show() el.hide()

将自定义字体更改为"Arial"

对于您不想要焦点事件的元素,请在脚本底部添加以下代码: noFocusElem.off('focus'); 这将确保删除您可能错误添加的任何焦点处理程序

最后,在任何脚本之前放置CSS。众所周知,在应用内联样式后添加CSS规则可能会导致抖动,尤其是如果您正在使用line-height属性

希望这有所帮助 :)


0

我知道这个问题已经发布了一段时间,这可能有点冒险,但是还是试试吧:

也许作为一个起点,回到 Chrome 并查看复合层:

在地址栏中输入以下内容: about:flags

您将能够从其中启用复合边框。红色边框通常表示渲染问题:

http://www.chromium.org/developers/design-documents/gpu-accelerated-compositing-in-chrome

我发现有时候虽然Chrome浏览器存在渲染问题,但它处理得相当好,可以将这些问题隐藏起来。然而,在其他基于Webkit的浏览器中,结果可能更加明显(例如Android)。

我也看到过在使用z-index与正在被转换的内容同时使用时出现闪烁的情况。

无论如何,如果您解决了这个问题,那么了解您是如何解决的将会很棒。也许可以在自己的问题下发布一个答案?


0
一种避免花费时间修复加载延迟的方法是将页面设置为隐藏状态,然后通过加载使元素可见。如果您的页面加载速度较慢,您可能希望默认显示旋转标志,然后在加载完成后将其隐藏。这样您可以在您有空时回到问题上来解决它。

0

这只是我的个人意见。

我会尝试的第一件事: 首先在Chrome中输入“about:flags”(是的,我知道你没有使用Chrome)。找到“合成渲染层边框”并打开它。一旦启用此功能,您将大致了解正在呈现/硬件加速的内容。

请参阅:http://www.chromium.org/developers/design-documents/gpu-accelerated-compositing-in-chrome

并查看任何呈现问题。这些通常是由z-index引起的。尝试调整任何z-index并隐藏/显示某些元素,直到解决呈现问题。然后从那里开始。translate-z hack和opacity也可能会导致问题。

根据经验,我发现可以使用Chrome诊断其他Webkit浏览器中的呈现问题。在原生Android浏览器上闪烁是常见的情况。

其次:仔细查看焦点事件本身,并尝试阻止默认行为。对我来说似乎有点牵强,但还是试试吧。


0

我在使用自定义字体包时遇到过这种情况。这可能是问题所在吗?某些事件会导致自定义字体重新绘制,这可能会导致页面显示出轻微的“抖动”。

有时,手动设置所有父HTML元素的高度和宽度可以减少闪烁。


0

我没有测试过这个,所以如果它起作用,我会非常惊讶...但这是一个想法:

$(document).ready(function() {
  $(document).focus(function(e) {
    e.preventDefault();
  });
  $(document).click(function() {
      $(document).unbind();
  });
});

0

最近我遇到了同样的问题,并找到了解决方法。

检查一下是否有任何隐藏在屏幕外的内容,例如:

text-indent: -9999px;
left: -9999px;

从3D加速元素(包括子元素)中删除所有这些实例会使焦点跳跃停止。

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