我们得到了一个初步的方案:初始化时,所有的页面一次性全部置入 container,除了我们用到的两页,display 属性都设置为 none 。touchmove 的时候,只有这两页的 transform 属性有变化 。
touchmove 的过程,我们可以写成数学表达式:
s=f(x),x∈[0,sideLength]
s=f(x),x∈[0,sideLength]
x
x 表示手指滑动的距离,s
s 表示页面滑动距离,sideLength
sideLength 是当前滑动边的长度,如果是沿 y 轴滑动,则是页面高度 。写到这里,就跟时下很流行的「数据驱动」的概念很类似了 。我们要实现的就只有一个 render 函数,输入是用户的交互数据,输出是页面表现 。
手指离开屏幕后
当手指离开屏幕时,我们就已经知道了这次滑动的结果(向上还是向下?翻页还是回弹?),要实现的只是动画效果,我们有两个选择:
方案一:复用 touchmove 的 render 逻辑,按照手指滑动的速度,使用 requestAnimationFrame 控制动画;
方案二:使用 css3 transition 动画;
方案一的优点在于:可以在手指滑动和动画过程使用同样的 render 函数,最大限度复用了代码,逻辑统一;同时可以精确控制动画的每一帧,动画曲线会比较流畅 。缺点就是可能存在的性能问题 。方案二跟方案一刚好相反 。其实说到底还是 js 动画 vs css 动画的问题 。
动画性能实验
为了比较两个方案在 H5 翻页动画上的性能优劣,我们取一个稍微复杂点的例子:
H5:百度无人车招聘的 H5
动画:从第 1 页翻到第 2 页
CPU: 6 * slowdown
浏览器:Chrome 61.0.3163.100(64 位)
js 动画方案:点击这里
css 动画方案:点击这里

文章插图
js 翻页动画方案,Profile 结果

文章插图
css 翻页动画方案,Profile 结果
通过实验我们可以看到,js 的动画过程中,帧率大多维持在 30 fps 上下 。而 css 动画,基本都在 60 fps 上下 。而且在动画过程中,明显感觉 js 动画有卡顿 。这种情况在一些 CPU 和显卡配置相对低的 Android 机型上尤为明显 。对于这个问题有兴趣的同学,可以看一下 swiper 库的 raf 分支,这是本次对比测试所用到的 js。
所以,尽管 js 的动画方案看起来比较「优雅」,能用「数据驱动」的理念,统一解决滑动过程和动画过程的问题 。实际上性能有瓶颈,我们只能在手指离开屏幕后,采用 css 的动画方案以保证性能 。正应了一句话「能用 css 做的,绝对不要用 js 解决」 。
实施方案
下图形象地展示了我们实施的基本思路,只有两页:
currentPage :当前页面
activePage:即将要翻到的下一页
其余的页面都是初始化的时候加载进 DOM 结构,但是 display 为 none 并且 z-index 都是 0 。这里展示「层叠」的状态是为了更形象的展示 。

文章插图
swiper 原理图
为了方便获取页面,我们采用双向链表保存页面结构 。每个 page 具有 prev 和 next 分别指向上一个和下一个 page 。
我们重点要关注的是,怎么样确定 activePage ?即下一个要去到的页面 。答案很简单,其实,当用户开始触碰屏幕,并且滑动的时候,就能确定了:
- 滑动距离 x < 0,表示页面向上滑动,此时 activepage = currentPage.next
- 滑动距离 x > 0,表示页面向下滑动,此时 activepage = currentPage.prev
我们举的例子中的翻页效果是最普通的滑动效果 。怎么样扩展支持立方体、翻转等效果呢?可以回头看看「手指离开屏幕前」部分,我们提出了 s=f(x)
s=f(x),x
x 是用户滑动距离,s
s 是页面滑动距离 。我们把 s
s 扩展一下,变成「页面翻转角度」或「页面缩放比率」,就可以支持其他的效果了 。
事实上,我们在滑动的时候,本身就是使用 css3 的 transform 属性,将其中的 translate, rotate, scale 适当的组合就能做出千变万化的翻页效果了 。
更令人愉悦的动画
这里指的是 animation-timing-function,拿最简单的滑动效果举例 。如果是线性的函数,用户滑动的速度始终等于页面滑动速度 。而「感觉上」更流畅、更灵敏的应该是:刚开始页面滑动速度大于用户滑动速度,随着翻页的进行,两者趋于相同,过了某个点后,单位时间内,页面滑动速度开始逐渐小于用户滑动速度,将速度表示为距离,就可以得到 x
推荐阅读
- 洗发水和护发素先用哪一个?顺序别搞错,不然头发越洗越油
- 十大口感顺滑威士忌 威士忌排名
- 你们知道散步有助于顺产吗?
- 三杯香产地介绍
- 泰顺三杯香茶产地环境
- 网线水晶头接法顺序
- 打造v形脸 方法原来是这6种
- 伊隆·马斯克|终身成长:那些追求进步和成长的职场人,都在潜心打造的7大核心竞争力
- 知道饭店的鸡蛋汤为什么滑嫩好喝么?做法顺序很关键,学会你也行
- 梦见订婚是什么意思有什么预兆 梦见订婚不顺利什么寓意
