iPad Safari滚动会导致HTML元素消失并延迟重新出现



我目前正在为iPad Safari开发一个使用HTML5和jQuery的web应用程序。我遇到了一个问题,当我向下滚动到屏幕外的元素时,大的滚动区域会导致它们在延迟后出现。

我的意思是,如果我有一行图像(甚至是一个有梯度的div)在屏幕外,当我向下(或向上)滚动到它时,预期的行为是当我滚动到它的时候,元素出现在屏幕上。

但是,元素直到我将手指从屏幕上移开,滚动器完成所有动画后才会出现

这给我带来了一个非常明显的问题,让整个事情看起来波涛汹涌,尽管事实并非如此。我猜iPad Safari正试图节省内存。有什么办法可以防止这种波涛汹涌的情况发生吗?

此外,iPadASafari到底想做什么?

您需要欺骗浏览器以更有效地使用硬件加速。你可以用一个空的三维变换:

-webkit-transform: translate3d(0, 0, 0)

特别是,您需要在具有position:relative;声明的子元素上执行此操作(或者,只需全力以赴,对所有子元素执行此操作)。

这不是一个有保证的解决方案,但在大多数情况下都相当成功。

帽子提示:iOS 5 Native Scrolling–Grins&Gotchas

我以前使用translate3d。它产生了不想要的结果。基本上,在我与交互之前,它会剪掉并不渲染屏幕外的元素。所以,基本上,在横向方向上,我的网站有一半在屏幕外没有显示。这是一个iPad网络应用程序,因此我陷入了困境。

translate3d应用于相对定位的元素解决了这些元素的问题,但其他元素一旦离开屏幕就停止了渲染。除非我重新加载页面,否则我无法与(艺术品)交互的元素将永远不会再渲染。

完整的解决方案:

*:not(html) {
    -webkit-transform: translate3d(0, 0, 0);
}

现在,尽管这可能不是最";高效的";解决方案,它是唯一有效的。使用-webkit-overflow-scrolling: touch时,Mobile Safari不会渲染屏幕外的元素,或者有时渲染不稳定。除非translate3d应用于所有其他可能因该滚动而离开屏幕的元素,否则这些元素将在滚动后被截断。

(这是我问题的完整答案。我最初把科林·威廉姆斯的答案标记为正确答案,因为这有助于我找到完整的答案。社区成员@Slipp D.Thompson在我问了大约2.5年问题后编辑了我的问题,并告诉我我滥用了SO的问答格式。他还告诉我把这个作为答案单独发布。@科林·威廉姆斯,谢谢!答案和你链接到的文章让我尝试了CSS。所以,再次感谢,并希望这能帮助其他失去的灵魂。这无疑帮了我很大的忙!)

html以外的所有元素为目标:*:not(html)在我的案例中,其他元素也出现了问题。它修改了堆叠上下文,导致一些z索引中断。

我们应该更好地尝试针对正确的元素,并仅对其应用-webkit-transform: translate3d(0,0,0)

有时translate3D(0,0,0)不起作用。我们可以使用以下方法,针对正确的元素:

@keyframes redraw{
    0% {opacity: 1;}
    100% {opacity: .99;}
}
/* iOS redraw fix */
animation: redraw 1s linear infinite;

translate3d不起作用时,尝试添加透视。它总是对我有效

transform: translate3d(0, 0, 0);
-webkit-transform: translate3d(0, 0, 0);
perspective: 1000;
-webkit-perspective: 1000;

使用硬件加速CSS提高网站性能

静态地将-webkit-transform: translate3d(0,0,0)添加到元素中对我不起作用。

我动态应用此属性。例如,当一个页面滚动时,我在一个元素上设置-webkit-transform: translate3d(0,0,0)。然后经过短暂的延迟,我重置了这个属性,即-webkit-transform: none这种方法似乎奏效了。

谢谢你,科林·威廉姆斯为我指明了正确的方向

我在iOS 7上的iscroll 4.2.5也遇到了同样的问题。整个滚动元素消失了。

我试着按照这里的建议添加translate3d(0,0,0)。它已经解决了这个问题,但它禁用了iscroll";"啪"的一声;效应

该解决方案将"position:relative; z-index:1000;display:block"CSS属性赋予容纳滚动元素的整个容器,并且不需要将translate3d赋予子元素。

我在使用旧版本的Fancybox时遇到了同样的问题。

升级到v3将解决您的问题您只需添加:

html, body {
    -webkit-overflow-scrolling : touch !important;
    overflow: auto !important;
    height: 100% !important;
}

此时translate3d可能无法工作。在这些情况下,可以使用perspective

transform: translate3d(0, 0, 0);
-webkit-transform: translate3d(0, 0, 0);
perspective: 1000;
-webkit-perspective: 1000;

我很确定我刚刚用解决了这个问题

overflow-y: auto;

(根据您的需要,可能只有overflow: auto;也可以工作。)

在某些情况下,应用旋转和/或使用Z索引

旋转:现有的-webkit-transform声明来旋转元素可能不足以解决外观问题(如-webkit-transform: rotate(-45deg))。在这种情况下,您可以使用-webkit-transform: translateZ(0px) rotateZ(-45deg)作为技巧(注意旋转Z)。

Z索引:与旋转一起,可以定义正z-index属性,如z-index: 42。在我的情况下,"Rotation"下描述的上述步骤足以解决问题,即使translateZ(0px)为空。不过,我怀疑在这种情况下,Z指数可能首先导致了的消失和重新出现。在任何情况下,都需要保留z-index: 42属性——仅-webkit-transform: translateZ(42px)是不够的。

这是开发人员面临的一个非常常见的问题,主要是由于Safari不重新创建定义为position : fixed的元素的特性。

因此,要么改变位置属性,要么需要像其他答案中提到的那样应用一些破解。

固定仓位的问题&在iOS上滚动

在滚动

时更改为iOS Safari上固定的位置。在我的情况下(iOS PhoneGap应用程序),将translate3d应用于相关子元素并不能解决问题。我的可滚动元素没有设定高度,因为它是绝对定位的,我正在定义顶部和底部的位置。

添加最小高度(100像素)为我修复了它。

我在Framework7和Cordova项目中遇到了这个问题。我尝试了上面所有的解决方案。他们没有解决我的问题。

在我的例子中,我在同一个页面上使用了10多个CSS动画,并进行了无限旋转(transform)。我不得不删除这些动画。由于缺少一些视觉功能,现在还可以。

如果其他答案中的解决方案对您没有帮助,您可以开始删除一些动画。

-webkit-transform: translate3d(0, 0, 0);技巧对我不起作用

/* Parent */
height: 100vh;

将其更改为

height: auto;
min-height: 100vh;

解决了问题,以防其他人面临同样的情况。

在我的案例中,CSS没有解决这个问题。我在使用jQuery重新渲染按钮时注意到了这个问题。

$("#myButton").html("text")

试试这个:

$("#myButton").html("<span>text</span>")

最新更新