最近有个任务,做一个非常小的h5的应用,只有2屏,需要做横向的全屏滑动切换和一些简单的动画效果,之前做这种东西用的是fullpage.js和jquery,性能不是很好,于是就想自己动手弄一个简单的东西来实现。最后我用zepto + hammer.js 和轮播的方式解决了这个问题,效果还不错,整个页面不开启Gzip时所有资源请求的数据大小为200KB左右。这篇文章总结下这个方法的实现思路。
效果演示(代码下载):
1. 实现要点1)滑屏借鉴bootstrap的carousel插件,不过完全没有它那个复杂,只需要借鉴它的轮播实现思路即可;
2)滑屏切换的触发,跟PC不一样,PC通常都是通过元素的点击回调来触发,对于滑屏的页面,完全可以利用window的hashchange事件来处理,这样只要通过超链接设置锚点或者通过js改变location.hash就能触发切换;
3)考虑到移动还得支持手势操作,可以使用hammer.js这个手势库,API非常简单易用;
4)动画效果可以用animate.css,不过不用把它所有的代码都弄到代码里,只需要拷贝需要的动画效果相关的代码即可;
5)替代jquery,首选zepto;
6)滑屏效果使用transition动画,为了能够响应动画结束的回调,可以考虑使用transition.js,这个也是Bootstrap提供的工具,不过它默认只能跟jquery使用,要对它稍微改变一下才能跟zepto联合使用。
这些要点说的比较粗糙,后面的内容会一一详细介绍。
2. html结构空的滑屏页的html结构是这样的:
html, body { height: 100%; -webkit-tap-highlight-color: transparent; } .container, .page { position: absolute; top: 0; left: 0; width: 100%; height: 100%; overflow: hidden; } .page { overflow: hidden; display: none; -webkit-transition: -webkit-transform .4s ease; transition: transform .4s ease; -webkit-backface-visibility: hidden; backface-visibility: hidden; }
.container与.page初始化的时候采用绝对定位,全屏布局。每一个section.page代表一页,并且默认不显示,所有页的定位都相同,也就是说如果所有页都显示的话,这些页会重叠在一块。
demo页的html结构是:
下一页1上一页下一页2上一页3
demo相关的css就不展示了。其中animated是应用animate.css需要的,animate.css是一个动画库,github上有。
3. 滑屏切换的实现思路滑屏切换就是通过js控制2个要滑动的页增加和删除以下定义的这一些css类实现的:
.page.page--active, .page.page--prev, .page.page--next { display: block; } .page.page--next, .page.page--active.page--active-right { -webkit-transform: translate3d(100%, 0, 0); transform: translate3d(100%, 0, 0); } .page.page--prev, .page.page--active.page--active-left { -webkit-transform: translate3d(-100%, 0, 0); transform: translate3d(-100%, 0, 0); } .page.page--next.page--next-left, .page.page--prev.page--prev-right, .page.page--active { -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); }
.page--active表示当前显示的页,页面初始化后,通过以下js调用,给第一页加上.page—active:
var $activePage; //初始化显示第一页 (function () { $activePage = $('#page-1'); $activePage.addClass('page--active'); })();
这样页面默认就显示了第一页。以向左滑屏说明这些css的使用原理:
第一步,找到下一页的section,添加page--next类,将它定位当前页的右边,为滑屏做准备;
第二步,找到当前页的section,给它添加page--active-left,由于这个类改变了translate3D属性的值,所以当前页会往左滑动一屏;
在第二步的同时,给下一页的section,添加page--next-left,由于这个类改变了translate3D属性的值,所以下一页会往左滑动一屏;
第三步,在当前页跟下一页滑屏动画结束后,找到原来的当前页,移除掉page--active和page--active-left类;
在第三步的同时,找到下一页,移除掉page--next和page--next-left类,添加page--active。
gif图说明如下:
向右滑屏原理类似:
第一步,找到上一页的section,添加page--prev类,将它定位当前页的左边,为滑屏做准备;
第二步,找到当前页的section,给它添加page--active-right,由于这个类改变了translate3D属性的值,所以当前页会往右滑动一屏;
在第二步的同时,给上一页的section,添加page--prev-right,由于这个类改变了translate3D属性的值,所以上一页会往右滑动一屏;
第三步,在当前页跟上一页滑屏动画结束后,找到原来的当前页,移除掉page--active和page--active-right类;
在第三步的同时,找到上一页,移除掉page--prev和page--prev-right类,添加page--active。
综合以上实现原理,封装成JS函数如下: