iOS 9 Safari:滚动时将元素更改为固定位置在滚动停止之前不会绘制
Posted
技术标签:
【中文标题】iOS 9 Safari:滚动时将元素更改为固定位置在滚动停止之前不会绘制【英文标题】:iOS 9 Safari: changing an element to fixed position while scrolling won't paint until scroll stops 【发布时间】:2015-12-28 18:25:42 【问题描述】:我一直在开发一个网站并利用相当不错的jQuery Sticky Kit 插件。它通过将position
属性切换为fixed
并在适当时返回来操作。在桌面上运行非常流畅,在移动设备上也可以接受。
或者至少以前是这样。 ios 9 带来了一个新的行为:如果一个元素的 position
从 static
/relative
/absolute
更改为 fixed
,而滚动动画正在进行,则该元素将变得不可见,直到滚动到达一站。奇怪的是,执行相反的更改(从fixed
到其他任何内容)都没有问题。
可以在the plugin's homepage 上找到一个工作示例。黑色导航栏(“示例参考”)应该是粘性的。最初它是位于页面中间的static
ly。当您向下滚动时,它会变为 fixed
并且(在 iOS 9 中)会消失,直到滚动停止。在桌面浏览器和 iOS 8 中的行为是正确的。
我有点希望典型的 CSS 解决方法:强制 3D 转换、禁用背面可见性等、模糊专有属性……但似乎没有任何效果。
既然“可粘”元素正在工作,我们是否要完全忘记它?
【问题讨论】:
如果您正在为 iOS 开发,您应该使用更好的解决方案,CSS 中的position: sticky
,尽管在前缀后面。您可以将 jQuery 插件用于其他所有内容,并在支持它的情况下使用适用于 iOS 的原生 CSS 解决方案(7+,如果我没记错的话)。
嗯,我正在为一切开发,但这允许使用混合方法。谢谢!
经过几个小时的反复试验,我可以得出结论,iOS 中对粘性标题的支持非常好,但是当您使用粘性列时,一切都变得混乱了。还是有点太绿了。
【参考方案1】:
我遇到了同样的问题,并且能够使用旧的“强制 3D 变换”技巧解决它。只需将要切换位置的元素设置为具有translate3d(0px,0px,0px)
的变换属性。确保在更改位置属性之前完成此操作。
【讨论】:
translate3d()
给我带来了一些布局问题,但 translateZ(0)
很有魅力
我在同一个 CSS 类上使用了 translate3d(),诀窍是它应该在更改位置或添加新类之前存在。谢谢!
这在 iOS 10 上似乎对我不起作用......它工作得很好,但我可以通过拖动固定元素'sticks'然后改变我的拖动方向来打破它另一个方向:-(
遗憾的是,在 Safari 9.0 上,这似乎对我不起作用。什么都没有。隐藏/显示、添加元素、添加 CSS 动画、访问 offsetHeight。我已经尝试了我能找到的每一个技巧,但在我从屏幕上移开滚动手指之前,标题栏仍然不会在固定位置重新绘制:(
我确实花了几天时间试图弄清楚如何修复我的粘性标题中的样式更改,直到滚动完全停止才生效,使整个事情看起来笨重和奇怪。将transform: translateZ(0);
添加到默认元素样式修复了此问题,现在样式转换在滚动期间顺利进行。精彩的!谢谢大家! (在装有 iOS 10.0.2 的 iPad Mini 上的 Chrome 和 Safari 中测试)【参考方案2】:
jQuery Sticky Kit 和其他类似的插件,即使是经过良好编码的,也在 iOS 9 上呈现这种行为,而且这种情况并不是第一次发生。这里的重点是 Firefox Safari 和 Safari Mobile 支持实验性的position: sticky;
,Google (Chromium) 也是如此,但由于集成问题,不得不暂时禁用它,您可以阅读更多关于它here。话虽如此,我的猜测是,position: sticky;
很快就会成为 CSS 规范的一部分,并得到所有主流浏览器的支持,因此我认为解决这个问题的最佳方法是使用 polyfill 而不是插件。当然,polyfill 不会涵盖这些插件提供的所有特性和功能。尽管如此,在许多情况下,使用 polyfill 就可以完成工作,这是所有主流浏览器都支持的强大而有效的解决方案。在我看来,这是目前要走的路。我个人使用stickyfill,尽管我确信野外的其他 polyfill 可以解决问题。我只能说,自从我开始使用 polyfill 而不是插件以来,我没有遇到任何浏览器兼容性问题。
【讨论】:
【参考方案3】:将此添加到您的固定元素使用混合: @include transform(translate3d(0px,0px,0px))
使用 CSS: translate3d(0px,0px,0px)
【讨论】:
使用“SCSS” 是错误的。您推荐使用的是 mixin,可能来自 compass... 使用 SCSS 并没有错,它只是省去了输入每个浏览器前缀的麻烦。 .... urm.... 除了这 [可能] 只是一个 iOS '.issue',因此您无需担心任何前缀【参考方案4】:我用一个额外的固定元素解决了这个问题。经过一些测试,我发现它是第一个固定的元素有这个问题。 2nd、3rd 等在 iOS 设备上运行良好。
所以,在你的 body openingtag 后面加上一个 div.fixed-fix:
.fixed-fix
position:fixed;
top:-1px;
height:1px;
width:100%;
background:white;
现在可以了! 固定的 div 必须 有一个背景色,否则它不会工作...
【讨论】:
这在 iOS10 上似乎对我不起作用。也许他们“修复”了它?我真的希望它会,因为我发现translate
选项非常有问题【参考方案5】:
我发现可以正常工作的唯一解决方案是禁用固定项目的直接子项上的 z-index 翻译,例如:
.is-sticky > *
-webkit-transform: translateZ(0);
【讨论】:
以上是关于iOS 9 Safari:滚动时将元素更改为固定位置在滚动停止之前不会绘制的主要内容,如果未能解决你的问题,请参考以下文章
在 iOS Safari 中输入焦点后无法滚动的模式(固定元素)