CSS3 动画在 iOS 上为什么会因为页面滚动也停止

html-css03

CSS3 动画在 iOS 上为什么会因为页面滚动也停止,第1张

不光是css3,gif动画也是,不信你打开一个gif 滚动的时候看它还动不动。

iOS最先响应屏幕反应。响应顺序依次为Touch——Media——Service——Core架构,当用户只要触摸接触了屏幕之后,系统就会最优先去处理屏幕显示也就是Touch这个层级,然后才是媒体(Media),服务(Service)以及Core架构。

所以说,当系统接收到Touch事件之后会优先响应,此时会暂停屏幕上包括js、css的渲染。这个时候不光是css动画不动了,哪怕页面没有加载完如果你手指头还停留在屏幕上那么页面也不会继续加载,直到你的手松开。

解决办法有两个,各有瑕疵:

不要使用 scroll 事件(此事件会被暂停),而是采用 touchmove(此事件会在用户触屏滚动的时候不断触发)。瑕疵是,在结束触屏后惯性滚动的时间里,touchmove 无法被触发了(scroll 当然也不行);

基于上一种方法,在所有的 touchmove 事件中,强行 preventDefault 阻止掉事件,然后根据 event.pageY 来手工设置所滑动元素的 scrollTop 值。当然,这样一来就没有了惯性滚动。

你也可以在 touchend 之后,手工模拟惯性滚动,计算速度以及速度衰减,可以参考各种各样的滚动插件。

节流函数是防止短时间内多次触发的一个处理函数

如:滚动事件,使用 addEventListener 方式添加监听器

为了使节流之后滚动更加的平滑, 我们可以使用 window.requestAnimationFrame() 来实现节流函数

在视窗中显示

当需要实现图片的懒加载或者是无限滚动时,需要确定元素是否出现在视窗中, 这样需要获取 elem.getBoundingClientRect()

注意: 每次调用 getBoundingClientRect 时都会触发回流, 这样会严重的影响性能,特别是在事件处理函数中,会更加的严重影响性能;

在 2016 年之后, 可以通过 Intersection Observer 这个 api 来解决问题, 它允许你追踪目标元素与其祖先元素或者视窗的交叉状态, 另外只有一部分元素出现在视窗中,哪怕只有 1 px , 也可以选择触发回调函数

滚动边界的问题:

当用户滚到末尾时, 整个页面都会开始滚动;

连锁滚动的表现, 当滚动有;元素到达底部时,可以改变页面的 overflow 属性或者在滚动元素的滚动事件处理函数中取消默认行为来解决这个问题

如果使用 JavaScript 处理, 那么处理的不是 scroll 事件, 而是每当用户使用鼠标滚轮 或者 是触摸板时 触发的是 wheel 事件

过度滚动对移动端的影响尤为的严重,下拉刷新的手势在 安卓的chrome 浏览器中,问题出现了,它会刷新整个页面, 而不是加载更多的内容;这个就会产生很多问题;

css 通过 overscroll-behavior 这个新属性解决问题。它通过控制元素滚动到尽头时的行为来解决 下拉刷新与 连锁滚动带来的问题。安卓的 glow 与苹果中的 rubber band。

准确的说, IE 与 Edge 实现了独有的 -ms-scroll-chaining 属性来控制连锁滚动;

微软浏览器已经准备实现 overscroll-behavior 这个属性

在触屏设备上,滚动的体验是一个很大的话题。

苹果公司开发了 惯性 滚动的专利;

css 有一个很hack 的方法;

只支持 webkit 内核,

但是我们会使用 touch 事件来解决这个问题,但是这个会对用户滚动体验造成很大的影响;

在现代的浏览器中,虽然知道如何使滚动变得平滑,但为了 确定滚动事件处理函数中是否执行了 阻止默认事件 ;可能任会花费 500 mm 来等待事件处理函数执行完毕

即使是一个空的事件监听函数, 从不取消任何行为,鉴于浏览器会期待 preventDefault 的调用, 也会对性能造成影响

为了告诉浏览器不去检测事件是否阻止了默认事件,在 whatwg dom 标准中,存在一个特性,来解决这个事件,

这个视频会看到带来的性能提升: https://www.youtube.com/watch?v=NPM6172J22g

此文借鉴: http://caibaojian.com/css-scroll.html