移动Safari浏览器上,JavaScript DOM 在touchmove事件中的更改要延迟到滚动结束才会生效。

16
在移动 Safari 中,在处理元素的 touchmove 过程中,我更改了该元素的 className。不幸的是,在用户滚动期间或在惯性滚动的末尾之前,视觉变化不会立即发生。
我该怎么做才能使 className 立即可见?
更多信息:显然,这不仅限于 className 更改,而是似乎任何对 DOM 的更改,例如 innerHTMLstyle
3个回答

15

这个网站是我自己建的,要绕过这个限制的方法就是不使用内置浏览器功能滚动页面,而是模拟滚动。JavaScript监听滚轮和键盘事件,并将主容器的CSS top属性缓动到其自己的'scrollTop'值。右侧的滚动条当然是自定义的JS滚动条,在这种情况下它与相同的内部'scrollTop'值同步。

整个网站实际上只是一个大的缓动,主时间线是它的scrollTop位置,所有子动画都在特定时间触发。JS没有被压缩所以可以查看ScrollAnimator.js文件,里面都有详细解释。


有人能提供一个链接吗?那个网站在哪里? - Gregory Magarshak
链接在上面的评论中 https://victoriabeckham.landrover.com/INT 对于我来说,使用Mac / Firefox上的双指触控板滚动页面无效。 - chmac
2
上面的链接似乎已经失效了。有人可以发布一下示例代码吗? - StoicJester
1
在链接消失之前,如果能够包含ScrollAnimator.js的代码就好了 :/ - Mike Garcia
这个是你们在找的那个吗?https://gist.github.com/domingl/6005178 - ey dee ey em

13

不幸的是,这是故意设计的。iOS Safari会将所有DOM操作排队到滚动或手势结束时才执行。实际上,在滚动期间DOM被冻结。

我本以为能在苹果开发者页面找到相关的参考资料,但我只找到了这个链接指向jQueryMobile: http://jquerymobile.com/test/docs/api/events.html

请注意,iOS设备在滚动期间冻结DOM操作,将它们排队,以便在滚动结束后应用。我们目前正在研究在滚动开始之前允许DOM操作应用的方法

希望这能帮到你!


1
非常不错的效果!我可能错了,但看起来他们正在覆盖滚动(在ScrollAnimator.js中的touchMoveHandler方法中,他们使用event.preventDefault),并且只是动画化可见区域,以使其看起来像正在发生滚动。可能是错误的,只看了几分钟,但看起来是这种情况! :) - Andy
有点晚了,但是Facebook主页在移动设备(iPad)上可以很好地完成这项工作。 - nbsp
Facebook Home是一个应用程序,而不是Web应用程序,因此不受iOS Safari问题的限制。 - Dancrumb
这在iOS8中已经修复。在iOS7上仅设置translateY也可以工作,尽管有点卡顿。 - Paul Hachmang
@PaulHachmang 在iOS Safari上它肯定还没有被修复。我正在使用iOS9,问题仍然存在。 - ey dee ey em
显示剩余3条评论

4

只需将位置更改为-webkit-sticky。不要设置顶部,这样它看起来就像普通元素,但表现为固定元素。而且,您可以立即更新其样式,除了位置。


这在iOS和新版本的桌面Safari中运行得非常好。我为标题所做的特别针对iOS使用了这个属性,其他所有东西都使用了fixed,这是因为兼容性的原因。有关此属性的更多信息,请参见:http://updates.html5rocks.com/2012/08/Stick-your-landings-position-sticky-lands-in-WebKit - loriensleafs
这太棒了!我已经为了寻找在touchmove期间动画某些东西的解决方案而苦恼了好几天,而position: sticky;正是我所需要的。我自己永远想不到这个。非常感谢你! - beefchimi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接