iPad Safari 滚动会导致 HTML 元素消失并延迟重新出现
Posted
技术标签:
【中文标题】iPad Safari 滚动会导致 HTML 元素消失并延迟重新出现【英文标题】:iPad Safari scrolling causes HTML elements to disappear and reappear with a delay 【发布时间】:2012-04-06 03:34:30 【问题描述】:我目前正在为 iPad Safari 开发一个使用 html5 和 jQuery 的 Web 应用程序。我遇到了一个问题,其中较大的滚动区域会导致屏幕外的元素在我向下滚动到它们时出现延迟。
我的意思是,如果我有一排在屏幕外的图像(甚至是带有渐变的 div),当我向下(或向上)滚动到它时,预期的行为 是让元素在我滚动到它时出现在屏幕上。
但是,元素不会出现,直到我将手指从屏幕上移开并且滚动条完成所有动画。
这给我造成了一个非常明显的问题,使整个事情看起来波涛汹涌,尽管事实并非如此。我猜 iPad Safari 正在尝试做一些事情来节省内存。有什么办法可以防止这种波动的发生吗?
此外,iPad Safari 究竟想要做什么?
【问题讨论】:
这个问题/解决方案帮助我解决了 jPanelMenu 1.3 CSS 转换版本的问题,它使我网站上的所有内容都变得不可见,直到我添加了上面的 sn-p。 使用 *:not(html) 会将 translate3d 应用到您网站的所有其他方面,我不推荐。当您向下滚动时,它会导致选项卡中的图像消失,等等,您可能习惯于仅在 3d 图像上看到的错误现在将出现在您网站的其他方面。 我有一些<svg>
元素表现出类似的延迟绘图/渲染。不幸的是,@ 987654322@ 导致了各种奇怪的行为,正如@JonathanTonge 指出的那样,可能会发生。但是,仅选择 <svg>
元素并使用 translate3d(0, 0, 0,);
似乎解决了我的滚动问题。
除了非常具体的用例,这是垃圾。真的搞砸了依赖绝对位置元素的布局。
请将答案发布为答案,而不是您的问题中的“编辑”。我知道你最喜欢你的答案,这很好,但 *** 有一种问答格式,当 Q 与 A 不同时效果最好。
【参考方案1】:
您需要欺骗浏览器以更有效地使用硬件加速。你可以用一个空的三维变换来做到这一点:
-webkit-transform: translate3d(0, 0, 0)
特别是,您需要在具有 position:relative;
声明的子元素上执行此操作(或者,全力以赴,对所有子元素执行此操作)。
这是一个有保证的修复,但它在大多数情况下都相当成功。
帽子提示:ios 5 Native Scrolling–Grins & Gotchas
【讨论】:
我也试过了。可悲的是,添加 translate3d 会切断之前正确显示的元素。我还需要对屏幕外的几个对象进行硬件加速,并且必须进行动画处理才能在屏幕上“飞入”。我正在使用 jQuery 的 animate(),它非常慢。我切换到使用硬件加速。尽管这加快了动画速度,但它产生了不稳定的结果,从某种意义上说,父(动画)div 的一些子元素被切断了。这在我使用 animate() 时没有发生。 @Colin Williams 你让我开心! :D 哇,这很可怕但很有效。谢谢。 链接已损坏。新链接:cantina.co/thought_leadership/… 缓存:web.archive.org/web/20131005175118/http://cantina.co/2012/03/06/… 金星男!我将它添加到可滚动 div 中的所有 li 元素中。噗。工作。【参考方案2】:我之前使用的是 translate3d。它产生了不想要的结果。基本上,它会切断并且不渲染屏幕外的元素,直到我与它们交互。因此,基本上,在横向方向上,我的屏幕外网站的一半没有被显示。这是一个 iPad 网络应用程序,因此我正在修复中。
将 translate3d 应用于相对定位的元素解决了这些元素的问题,但其他元素一旦离开屏幕就会停止渲染。除非我重新加载页面,否则我无法与之交互的元素(艺术品)将永远不会再次呈现。
完整的解决方案:
*:not(html)
-webkit-transform: translate3d(0, 0, 0);
现在,虽然这可能不是最“有效”的解决方案,但它是唯一有效的解决方案。使用-webkit-overflow-scrolling: touch
时,Mobile Safari 不会呈现屏幕外的元素,或者有时呈现不规则的元素。除非将 translate3d 应用于所有其他可能由于该滚动而离开屏幕的元素,否则这些元素将在滚动后被切掉。
(这是我问题的完整答案。我最初将Colin Williams' answer 标记为正确答案,因为它帮助我找到了完整的解决方案。社区成员@Slipp D. Thompson 编辑了我的问题, 在我问了大约 2.5 年后,告诉我我在滥用 SO 的问答格式。他还告诉我单独发布这个作为答案。 @科林威廉姆斯,谢谢!您链接到的答案和文章给了我一个尝试使用 CSS 的线索。所以,再次感谢,希望这能帮助其他一些迷失的灵魂。这肯定帮了我很大的忙!)
【讨论】:
哇。谢谢你。它为我的 phonegap/cordova 应用程序省了很多麻烦。就我而言,我必须将*:not(html)
更改为 body *
仅将-webkit-transform: translate3d(0, 0, 0);
应用于问题元素对我有用。就我而言,我使用的是ScrollMagic
这些都不适合我。一旦我向下滚动到某个点,窗口上方不再可见的东西就会被清理掉,以及视口中的一些元素。我注意到滚动时有一个非常轻微但明确无误的“震动”,之后元素被冲洗掉。 (即:smooth--jittery--smooth 行为,就像它在滚动时打嗝一样。)这是在 iPad 上。
顺便说一句,我刚刚发现在 iPad Air 2 上,当特定的屏幕元素(在本例中为导航栏)离开屏幕时,设备会“重新加载”该阻止 - 仅使用大版本,而不是页面加载的原始媒体版本。什么...
如果有人遇到和我一样的怪异——与本页描述的略有不同——我发现在 jQuery 中使用 $(window).width()
而不是 window.innerWidth
对IOS。谁知道呢。【参考方案3】:
定位除 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)
。它会解决你的问题。
对以正确元素为目标而不是用 * 污染一切的建议表示敬意【参考方案4】:
当translate3d不起作用时,尝试添加perspective。它总是对我有用
transform: translate3d(0, 0, 0);
-webkit-transform: translate3d(0, 0, 0);
perspective: 1000;
-webkit-perspective: 1000;
Increase Your Site’s Performance with Hardware-Accelerated CSS
【讨论】:
holy c$#@ 终于找到了 angular/ionic 的解决方案。-webkit-perspective: 1000;
啊,拯救了我的一天。为你 +1 ;)
这让我的 iOS 浏览器崩溃了。
-webkit-perspective: 1000;
为我做了 - 谢谢【参考方案5】:
静态添加-webkit-transform: translate3d(0,0,0)
对我来说不起作用。
我动态应用此属性。例如,当页面滚动时,我在一个元素上设置了-webkit-transform: translate3d(0,0,0)
。然后经过短暂的延迟,我重新设置了这个属性,即-webkit-transform: none
这种方法似乎有效。
谢谢Colin Williams for pointing me in the right direction.
【讨论】:
这个提示对我帮助很大,因为这些样式会产生一些不需要的副作用,我通常想避免。所以我使用 touchstart/touchend 事件来添加和删除它们。谢谢!【参考方案6】:我在 iOS 7 上使用 iscroll 4.2.5 时遇到了同样的问题。整个滚动元素消失了。
我已尝试按照此处的建议添加 translate3d(0,0,0)
。它已经解决了这个问题,但是它禁用了iscroll“snap”效果。
解决方案是将"position:relative; z-index:1000;display:block"
CSS 属性赋予包含滚动元素的整个容器,而无需将translate3d 赋予子元素。
【讨论】:
我使用这种技术解决了 android Chrome 上的类似问题。垂直滚动似乎比我尝试 translate3d 修复时表现得更好。在我的情况下,<body>
元素是我用于滚动的元素,并且简化版本有效:body position: relative; z-index: 0;
【参考方案7】:
我在使用旧版本的 Fancybox 时遇到了同样的问题。
升级到 v3 将解决您的问题或者您可以添加:
html, body
-webkit-overflow-scrolling : touch !important;
overflow: auto !important;
height: 100% !important;
【讨论】:
【参考方案8】:有时translate3d
可能不起作用。在这些情况下,可以使用perspective
transform: translate3d(0, 0, 0);
-webkit-transform: translate3d(0, 0, 0);
perspective: 1000;
-webkit-perspective: 1000;
【讨论】:
【参考方案9】:我很确定我刚刚解决了这个问题:
overflow-y: auto;
(根据您的需要,大概只是 overflow: auto;
也可以工作。)
【讨论】:
它对我没有任何作用,而接受的答案可能是不同的情况【参考方案10】:存在应用旋转和/或使用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)
是不够的。
【讨论】:
【参考方案11】:这是开发人员面临的一个非常普遍的问题,这主要是由于Safari's 属性未重新创建定义为position : fixed
的元素。
因此,要么更改位置属性,要么需要应用一些技巧,如其他答案中所述。
Issues with position fixed & scrolling on iOS
Change to position fixed on iOS Safari while scrolling
【讨论】:
【参考方案12】:就我而言(iOS PhoneGap 应用程序),将 translate3d 应用于相关子元素并不能解决问题。我的可滚动元素没有设置高度,因为它是绝对定位的,我正在定义顶部和底部位置。
添加 min-height(100 像素)为我修复了它。
【讨论】:
【参考方案13】:我在 Framework7 和 Cordova 项目中遇到了这个问题。我尝试了上述所有解决方案。他们没有解决我的问题。
在我的例子中,我在同一个页面上使用了 10 多个 CSS 动画并无限旋转(变换)。我不得不删除动画。现在还可以,只是缺少一些视觉功能。
如果其他答案中的解决方案对您没有帮助,您可能会开始消除一些动画。
【讨论】:
【参考方案14】:-webkit-transform: translate3d(0, 0, 0);
技巧对我不起作用。就我而言,我已将父母设置为:
/* Parent */
height: 100vh;
改成
height: auto;
min-height: 100vh;
解决了其他人面临的问题 同样的情况。
【讨论】:
【参考方案15】:就我而言,CSS 并没有解决这个问题。我在使用 jQuery 重新渲染按钮时注意到了这个问题。
$("#myButton").html("text")
试试这个:
$("#myButton").html("<span>text</span>")
【讨论】:
以上是关于iPad Safari 滚动会导致 HTML 元素消失并延迟重新出现的主要内容,如果未能解决你的问题,请参考以下文章
当 URL 包含片段时,iframe 会导致父元素在 Google Chrome 上向上滚动
IFRAMEs 和 iPad 上的 Safari,用户如何滚动内容?