ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

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

这对我来说是一个非常明显的问题,使整个事情看起来波涛汹涌,尽管事实并非如此。我猜 iPad Safari 正在尝试做一些事情来节省内存。有没有办法可以防止这种波涛汹涌的发生?

此外,iPad Safari 究竟想做什么?

这个问题/解决方案帮助我解决了 jPanelMenu 1.3 CSS 转换版本的问题,它使我网站上的所有内容都变得不可见,直到我添加了上面的代码片段。
使用 *:not(html) 会将 translate3d 应用于您网站的所有其他方面,我不推荐。当您向下滚动时,它将导致选项卡中的图像消失等,您可能习惯于仅在 3d 图像上看到的错误现在将出现在您网站的其他方面。
我有几个 <svg> 元素表现出类似的延迟绘制/渲染。不幸的是,*:not(html) { ... } 导致了各种奇怪的行为,正如@JonathanTonge 指出的那样,可能会发生。但是,仅选择 <svg> 元素并使用 translate3d(0, 0, 0,); 似乎解决了我的滚动问题。
除了非常特定的用例外,这是垃圾。真的弄乱了依赖于绝对位置元素的布局。
请在您的问题中发布答案,而不是“编辑”。我知道你最喜欢你的答案,这很好,但 StackOverflow 有一个问答格式,当 Q 与 A 不同时效果最好。

N
N3R4ZZuRR0

您需要欺骗浏览器以更有效地使用硬件加速。您可以使用空的 3D 变换来做到这一点:

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

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

这不是一个有保证的修复,但它在大多数情况下都相当成功。

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


我也试过了。可悲的是,添加 translate3d 会切断之前正确显示的元素。我还需要对屏幕外的几个对象进行硬件加速,并且必须进行动画处理才能在屏幕上“飞入”。我正在使用 jQuery 的 animate(),它非常慢。我切换到使用硬件加速。尽管这加快了动画速度,但它产生了不稳定的结果,因为父(动画)div 的一些子元素被切断了。这在我使用 animate() 时没有发生。
@Colin Williams 你让我很开心! :D
哇,这很可怕,但很有效。谢谢你。
黄金怪星人!我将它添加到可滚动 div 中的所有 li 元素中。噗。工作。
P
Peter Mortensen

我之前使用的是 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 的问答格式。他还告诉我将此作为答案单独发布。@Colin Williams,谢谢!答案和您链接到的文章给出了我是一个尝试使用 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 有很大的影响。谁知道。
P
Peter Mortensen

针对除 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)。它会解决你的问题。
感谢建议以正确的元素为目标而不是用 * 污染一切
P
Peter Mortensen

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

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


神圣的 c$#@ 终于找到了 angular/ionic 的解决方案。 -webkit-perspective: 1000;
啊,拯救了我的一天。为你 +1 ;)
这使我的 iOS 浏览器崩溃。
-webkit-perspective: 1000; 为我做的 - 谢谢
P
Peter Mortensen

-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 事件来添加和删除它们。谢谢!
动态应用这种风格对我来说效果很好。这是一个 React 应用程序,所以我制作了一个挂钩,它返回 className 以根据其子项应用于滚动容器。每当子项发生更改时,或在 setTimeout 完成后,挂钩会在 .ios-fix 和空字符串之间切换类,以便您可以使用 <div className={className}> 应用它。
P
Peter Mortensen

我在 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; }
P
Peter Mortensen

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

升级到 v3 将解决您的问题,或者您可以添加:

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

P
Peter Mortensen

在时间 translate3d 可能不起作用。在这些情况下,可以使用 perspective

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

D
David Notik

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

overflow-y: auto;

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


它对我没有任何作用,而接受的答案可能是另一种情况
S
Stefan Zurfluh

存在应用旋转和/或使用 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) 是不够的。


P
Peter Mortensen

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

因此,如其他答案中所述,要么更改位置属性,要么需要应用一些技巧。

Issues with position fixed & scrolling on iOS

Change to position fixed on iOS Safari while scrolling


P
Peter Mortensen

就我而言(一个 iOS PhoneGap 应用程序),将 translate3d 应用于相关子元素并不能解决问题。我的可滚动元素没有设置高度,因为它是绝对定位的,我正在定义顶部和底部位置。

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


P
Peter Mortensen

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

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

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


P
Peter Mortensen

-webkit-transform: translate3d(0, 0, 0); 技巧对我不起作用。就我而言,我已将父母设置为:

/* Parent */
height: 100vh;

将其更改为

height: auto;
min-height: 100vh;

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


P
Peter Mortensen

就我而言,CSS 没有解决这个问题。我在使用 jQuery 重新渲染按钮时注意到了这个问题。

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

尝试这个:

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