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


165

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

我的意思是,如果我有一排不在屏幕上的图像(甚至是带有渐变的div),则当我向下(或向上)滚动到该图像时,预期的行为是该元素在屏幕上显示为我正在滚动到它。

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

这给我造成了一个非常明显的问题,尽管看起来并非如此,但整个事情看起来却很不稳定。我猜想iPad Safari正在尝试做一些事情来节省内存。有什么方法可以防止这种不连贯现象的发生。此外,如果有人能阐明iPad Safari的实际用途,我也将不胜感激。


这个问题/解决方案帮助我解决了jPanelMenu 1.3 CSS Transforms版本的问题,该版本使我网站上的所有内容都无法显示,直到添加了以上代码段为止。
第75长号

2
使用*:not(html)会将translate3d应用于您网站的所有其他方面,我不建议这样做。当您向下滚动时,这将导致选项卡中的图像消失,等等,您可能习惯于仅在3d图像上看到的错误现在也将出现在网站的其他方面。
乔纳森·汤格

1
我有一些<svg>要素表现出类似的延迟绘制/渲染。不幸的是,*:not(html) { ... }导致了各种奇怪的行为,如@JonathanTonge所指出的那样。但是,仅选择<svg>元素并使用translate3d(0, 0, 0,);似乎解决了我的滚动问题。
Zephyr Mays 2014年

除了非常特殊的用例,这都是垃圾。确实搞砸了依赖于绝对位置元素的布局。
2014年

2
请张贴答案作为答案,而不是问题中的“编辑”。我知道您最喜欢您的答案,这很好,但是当Q与A不同时,StackOverflow的Q&A格式效果最佳。
Slipp D. Thompson 2014年

Answers:


184

您需要欺骗浏览器以更有效地使用硬件加速。您可以使用空的3d变换来执行此操作:

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

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

不是有保证的修复程序,但在大多数情况下都相当成功。

帽子提示:https : //web.archive.org/web/20131005175118/http : //cantina.co/2012/03/06/ios-5-native-scrolling-grins-and-gothcas/


3
我也尝试过。可悲的是,添加一个translate3d会砍掉之前正确显示的元素。我还需要为两个不在屏幕上的对象进行硬件加速,并且必须对其进行动画处理才能“飞入”屏幕。我使用的是jQuery的animate(),速度非常慢。我切换到使用硬件加速。尽管这加快了动画的速度,但是从父(动画)div的某些子元素被切掉的意义上讲,它产生了不稳定的结果。当我使用animate()时,这没有发生。
codeBearer 2012年

1
@科林·威廉姆斯,你今天过得很愉快!:D
路加福音

9
哇,那太可怕了,但是有效。谢谢。
蒂姆·唐


1
黄金怪胎明星!我将其添加到可滚动div中的所有li元素中。of 工作了
布莱恩·约翰逊

68

这是我问题的完整答案。我最初将@Colin Williams的答案标记为正确的答案,因为它帮助我获得了完整的解决方案。在我问了2.5年后,@ Slipp D. Thompson的一个社区成员编辑了我的问题,并告诉我我正在滥用SO的Q&A格式。他还告诉我将其单独发布作为答案。因此,这是解决我的问题的完整答案:

@科林·威廉姆斯,谢谢!您的答案和您链接到的文章给了我引导,尝试使用CSS。

因此,我之前使用过translate3d。它产生了不良的结果。基本上,它将剔除屏幕上的元素,并且不进行渲染,直到我与它们进行交互为止。因此,基本上,从横向看,没有显示我的一半不在屏幕上的网站。这是一个iPad Web应用程序,由于我已修复。

将translate3d应用于相对定位的元素可以解决这些元素的问题,但是其他元素一旦脱离屏幕就停止渲染。我无法与之交互的元素(图稿)将永远不会再次呈现,除非重新加载页面。

完整的解决方案:

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

现在,尽管这可能不是最“有效”的解决方案,但它是唯一可行的解​​决方案。使用时,Mobile Safari不会渲染屏幕外的元素,有时甚至无法正常渲染-webkit-overflow-scrolling: touch。除非将translate3d应用于由于该滚动而可能会在屏幕外显示的所有其他元素,否则这些元素将在滚动后被切掉。

因此,再次感谢,希望这对其他迷路者有所帮助。这无疑帮助了我很多时间!


2
哇。谢谢你 它为我的phonegap / cordova应用程序节省了很多麻烦。在我来说,我不得不改变*:not(html),以body *
匿名

9
仅适用-webkit-transform: translate3d(0, 0, 0);于问题元素对我来说是有效的。就我而言,我使用的是ScrollMagic
fidev

这些都不对我有用。当我向下滚动到某个点时,窗口上方不再可见的内容以及视口中的某些元素就会被覆盖。在滚动之后,我注意到一个非常轻微但无误的“颠簸”,之后这些元素都被压缩了。(即:平滑-抖动-平滑行为,例如在滚动过程中会打ic。)这在iPad上。
cbmtrx

顺便说一句,我刚刚发现,在iPad Air 2上,当特定的屏幕元素(在本例中为导航栏)离开屏幕时,设备会“重新加载”该阻止文件-仅使用大版本,而不是原始介质。页面加载的位置。什么...
cbmtrx

如果有人遇到与我相同的怪异之处(与本页上描述的内容略有不同),我发现在iOS 中使用$(window).width()代替window.innerWidthjQuery会带来很大的不同。谁知道。
cbmtrx

13

定位除html之外的所有元素: *:not(html) 就我而言,导致其他元素出现问题。它修改了堆栈上下文,导致某些z-index中断。

我们最好尝试针对正确的元素并仅-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;

我面临着同样的问题。您可以使用body *选择器代替*:not(html)。它将解决您的问题。
KUNAL

对于以正确元素为目标而不是用*污染一切的建议,我很
荣幸

7

当translate3d无法正常工作时,请尝试添加透视图。它总是对我有用

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

http://blog.teamtreehouse.com/increase-your-sites-performance-with-hardware-accelerated-css


最终,C $#@是角/离子的解决方案。 -webkit-perspective: 1000;
lilbiscuit

啊,救了我一天。为您+1;)
奥马尔·巴希尔

这使我的iOS浏览器崩溃了。
Andreas Richter

-webkit-perspective: 1000;为我做了吗-谢谢
jHilscher

2

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

我动态应用此属性。例如,当滚动页面时,我设置-webkit-transform: translate3d(0,0,0)了一个元素。然后,在短暂的延迟之后,我重置了此属性,也就是说,-webkit-transform: none 这种方法似乎可行。

谢谢@Colin Williams指出正确的方向。


这个提示对我很有帮助,因为这些样式会带来一些不必要的副作用,所以我通常要避免使用。因此,我使用touchstart / touchend事件添加和删除它们。谢谢!
Windwalker

1

我在ios7上使用iscroll 4.2.5存在相同的问题。整个滚动元素便消失了。我尝试translate3d(0,0,0)按照此处的建议进行添加,它已经解决了问题,但是禁用了iscroll的“快照”效果。该解决方案附带为"position:relative; z-index:1000;display:block"包含滚动元素的整个容器赋予css属性,而无需将translate3d赋予子元素。


我使用这项技术来解决Android Chrome上的类似问题。垂直滚动似乎比我尝试了transform3d修复时要好。在我的情况下,<body>元素是我用于滚动的元素,并且简化了版本:body { position: relative; z-index: 0; }
BumbleB2na

1

有时translate3d可能无法使用,在这种情况下perspective可以使用

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

0

我非常确定我只是用以下方法解决了这个问题:

overflow-y: auto;

(大概也overflow: auto;可以根据您的需要工作。)


它对我无济于事,而被接受的答案却可能是不同的情况
Tony

0

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

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

Z索引:您可以与旋转一起定义一个正z-index属性,例如z-index: 42。就我而言,“轮换”下描述的上述步骤足以解决问题,即使是空的translateZ(0px)。我怀疑尽管在这种情况下Z索引可能首先导致了消失和重新出现。无论如何,都z-index: 42需要保留该属性- -webkit-transform: translateZ(42px)仅不够。


0

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

因此,如其他答案中所述,要么更改position属性,要么需要进行一些修改。

链接1

链接2


0

就我而言(一个iOS Phonegap应用程序),将translate3d应用于相对的子元素并不能解决问题。我的可滚动元素没有设置高度,因为它的位置绝对正确,我正在定义顶部和底部位置。对我来说固定的是添加了最小高度(100像素)。


0

使用较旧版本的Fancybox时,我遇到相同的问题。升级到v3将解决您的问题,或者您可以添加:

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

0

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

就我而言,我在同一页面上使用了十多个css动画,并且进行了无限旋转(变换)。我必须删除动画。现在还可以缺少一些视觉功能。

如果以上解决方案对您没有帮助,则可以开始删除一些动画。


0

-webkit-transform: translate3d(0, 0, 0);招对我没用。就我而言,我已将父母设为:

// parent
height: 100vh;

更改为:

height: auto;
min-height: 100vh;

解决了其他人面临相同情况的问题。


0

就我而言,CSS无法解决问题。我在使用jQuery重新呈现按钮时注意到了问题。

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

试试这个

$("#myButton").html("<span>text</span>")
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.