H5 左右滑屏切页原理
采用HTML5 触摸事件(Touch) 和 CSS3动画(Transform,Transition)来实现的,效果图如下所示,本文简单说一下其实现原理和主要思路。
实现原理
手指在屏幕上滑动时,页面跟随移动
当手指离开屏幕时,计算手指在屏幕上停留的时间
如果停留时间小于300ms,则认为是快速滑动切换,页面切换到下一页
如果停留时间大于300ms,则认为是慢速滑动,慢速滑动按如下规则处理:
如果滑动距离小于屏幕宽度的50%,则回退到上一页
如果滑动距离大于屏幕宽度的50%,则切换到下一页
对于多手指触摸操作:
- 第一个手指触摸时,正常滑动
- 第二个手指按下时,不做任何响应操作,继续原有的滑动
- 当任意一个手指离开屏幕时,结束滑动,剩余的手指操作不做任何处理
- 当第二个手指再次按下时,触发新的滑动开始,但由于获取的是touches[0],因此,第一个手指移动才会引起页面的滑动
- 支持多手指同时按下时进行滑动
假设有4个页面,每个页面占屏幕100%宽,则创建一个容器,将其宽度(width) 设置为400%,并让这4个页面平分整个容器,最后将容器的默认位置设置为0,overflow设置为hidden,这样屏幕就默认显示第一个页面。
<article class="slide-content"><section class="slide-item" data-index="0"><h3>页面-1</h3></section><section class="slide-item" data-index="1"><h3>页面-2</h3></section><section class="slide-item" data-index="2"><h3>页面-3</h3></section><section class="slide-item" data-index="3"><h3>页面-4</h3></section>
</article>
css样式:
.slide-content,.slide-item {height: 100%;}.slide-content {width: 400%;display: -webkit-box;overflow: hidden;-webkit-transform: translate3d(0, 0, 0);transform: translate3d(0, 0, 0);backface-visibility: hidden;}.slide-item {-webkit-box-flex: 1;width: 0;}
主要思路
注册touchstart,touchmove和touchend事件,当手指在屏幕上滑动时,使用CSS3的transform来实时设置slide-content的位置,在这里采用translate3d来代替translateX,translate3d可以主动开启手机GPU加速渲染,页面滑动更流畅。
从手指放在屏幕上、滑动操作、再到离开屏幕是一个完整的操作过程,对应的操作会触发如下事件:
手指放在屏幕上:ontouchstart
手指在屏幕上滑动:ontouchmove
手指离开屏幕:ontouchend
我们需要捕获触摸事件的这三个阶段来完成页面的滑动:
ontouchstart: 初始化变量, 记录手指所在的位置,记录当前时间
// 手指放在屏幕上scrollContainer.addEventListener("touchstart", function (e) {e.preventDefault();// 单手指触摸或者多手指同时触摸,禁止第二个手指延迟操作事件if (e.touches.length === 1 || isTouchEnd) {var touch = e.touches[0];startX = touch.pageX;startY = touch.pageY;initialPos = currentPosition; // 本次滑动前的初始位置scrollContainer.style.webkitTransition = ""; // 取消动画效果startT = +new Date(); // 记录手指按下的开始时间isMove = false; // 是否产生滑动isTouchEnd = false; // 当前滑动开始}});
ontouchmove: 获得当前所在位置,计算手指在屏幕上的移动差量deltaX,然后使页面跟随移动
//手指在屏幕上滑动,页面跟随手指移动scrollContainer.addEventListener("touchmove", function (e) {e.preventDefault();// 如果当前滑动已结束,不管其他手指是否在屏幕上都禁止该事件if (isTouchEnd) return;var touch = e.touches[0];var deltaX = touch.pageX - startX;var deltaY = touch.pageY - startY;var translate = initialPos + deltaX; // 当前需要移动到的位置// 如果translate>0 或 < maxWidth,则表示页面超出边界,即滑动范围是[maxWidth, 0]if (translate > 0) {//最左边是0translate = 0;}if (translate < maxWidth) {//最右边是maxWidth,负值translate = maxWidth;}deltaX = translate - initialPos; //滑动到左右边界时,按照滑动范围计算本次水平能滑动的最大距离(超出不算)transform.call(scrollContainer, translate);isMove = true;moveLength = deltaX;direction = deltaX > 0 ? "right" : "left"; // 判断手指滑动的方向});
ontouchend:手指离开屏幕时,计算屏幕最终停留在哪一页。首先计算手指在屏幕上的停留时间deltaT,如果deltaT<300ms,则认为是快速滑动,相反则是慢速滑动,快速滑动和慢速滑动的处理是不同的:
- 如果是快速滑动,则让当前页面完整的停留在屏幕中央(需要计算当前页面还有多少需要滑动)
- 如果是慢速滑动,还需要判断手指在屏幕上滑动的距离,如果滑动的距离没有超过屏幕宽度50%,则要回退到上一页,相反则要停留在当前页面
//手指离开屏幕时,计算最终需要停留在哪一页scrollContainer.addEventListener("touchend", function (e) {e.preventDefault();var translate = 0;var deltaT = +new Date() - startT; // 计算手指在屏幕上停留的时间if (isMove && !isTouchEnd) {// 发生了滑动,并且当前滑动事件未结束isTouchEnd = true; // 标记当前完整的滑动事件已经结束// 使用动画过渡让页面滑动到最终的位置scrollContainer.style.webkitTransition ="0.3s ease -webkit-transform";if (deltaT < 300) {// 如果停留时间小于300ms,则认为是快速滑动,无论滑动距离是多少,都停留到下一页if (currentPosition === 0 && translate === 0) {//没有滑动页面return;}//不管滑动多少,最终只滑动一页translate =direction === "left"? currentPosition - (pageWidth + moveLength): currentPosition + pageWidth - moveLength;// 如果最终位置超过边界位置,则停留在边界位置translate = translate > 0 ? 0 : translate; // 左边界translate = translate < maxWidth ? maxWidth : translate; // 右边界} else {// 如果滑动距离小于屏幕的50%,则退回到上一页if (Math.abs(moveLength) / pageWidth < 0.5) {//currentPosition为当前滑动到的距离,即之前划过的页码数的距离+本次滑动的距离,而moveLength是本次滑动的距离=》之差就是之前划过的页码数的距离//若当前为未滑动过,那么初始translateY为0,currentPosition等于moveLength滑动的距离,之差为0及translateY为0不会切换页面//若滑动到第二页,那么初始translateY为-pageWidth,则在此页码上移动currentPosition为-pageWidth+moveLength(在原有滑动基础上滑动了moveLength),所以之差仍为currentPosition,即不会切换页面translate = currentPosition - moveLength;} else {// 如果滑动距离大于屏幕的50%,则滑动到下一页//currentPosition - moveLength可只是保留上次滑动的距离,那么+pageWidth和-pageWidth就是向右或向左滑动一页translate =direction === "left"? currentPosition - (pageWidth + moveLength): currentPosition + pageWidth - moveLength;translate = translate > 0 ? 0 : translate;translate = translate < maxWidth ? maxWidth : translate;}}transform.call(scrollContainer, translate); // 执行滑动,让页面完整的显示到屏幕上pageNow = Math.round(Math.abs(translate) / pageWidth) + 1; // 计算当前的页码setTimeout(function () {setPageNow(); // 设置页码,DOM操作需要放到异步队列中,否则会出现卡顿}, 100);}});
除此之外,还要计算当前页面是第几页,并设置当前页码
//计算当前的页码
pageNow = Math.round(Math.abs(translate) / pageWidth) + 1;setTimeout(function(){//设置页码,DOM操作需要放到子线程中,否则会出现卡顿this.setPageNow();
}.bind(this),100);
具体实例:https://camillezj.github.io/Swiper.html(用手机模拟器或手机查看效果)
代码:https://github.com/camilleZJ/camillezj.github.io/blob/master/Swiper.html
H5 左右滑屏切页原理相关推荐
- h5实现上下滑动切页
安卓系统下正常使用,ios系统下无法滑动切页,那位大神可以找到问题,多谢大佬 <!DOCTYPE html> <html lang="en"> <he ...
- H5视差滑屏,Swiper的Parallax属性
参考文档:Swiper中文网-轮播图幻灯片js插件,H5页面前端开发 标准地图来源:自然资源部地图技术审查中心承办的标准地图服务 想要了解和下载更多关于 标准地图 的内容,欢迎访问中国地图出版集团官网 ...
- html 滑屏 效果,HTML5 web app实现手动页面滑屏效果
现在很流行在H5页面滑屏的效果,特别是在微信浏览器窗口中,几乎很多推广的活动是使用到上下滑屏,一开始和前端的同事一起合作写滑屏效果花费了很多的时间,而且写出来的页面在浏览器的兼容上踩了很多坑,于是果断 ...
- [重磅] 让HTML5达到原生的体验 系列之中的一个 避免切页白屏
非常多人都想.甚至曾使用HTML5开发跨平台App.而且想达到原生App的体验. 最后的结果都是无奈的放弃.HTML5貌似美好,但坑太多.想做到原生App的体验差点儿不可为. 也曾有过著名的faceb ...
- jsp页面div上下滑动_H5单页面手势滑屏切换原理
H5单页面手势滑屏切换是采用HTML5 触摸事件(Touch) 和 CSS3动画(Transform,Transition)来实现的,效果图如下所示,本文简单说一下其实现原理和主要思路. 实现原理 假 ...
- 提升html5的性能体验系列之一避免切页白屏
窗体切换白屏的现实问题 HTML5的性能比原生差很多,比如切页时白屏.列表滚动不流畅.下拉刷新和上拉翻页卡顿. 在低端Android手机上,很多原生App常用的功能和体验效果都很难使用HTML5技术模 ...
- html5页面图片切换,HTML5单页面手势滑屏切换原理
H5单页面手势滑屏切换是采用HTML5 触摸事件(Touch) 和 CSS3动画(Transform,Transition)来实现的,效果图如下所示,本文简单说一下其实现原理和主要思路. 1.实现原理 ...
- 手机 html5 hammer drag widget,Hammer.js+轮播原理实现简洁的滑屏功能
最近有个任务,做一个非常小的h5的应用,只有2屏,需要做横向的全屏滑动切换和一些简单的动画效果,之前做这种东西用的是fullpage.js和jquery,性能不是很好,于是就想自己动手弄一个简单的东西 ...
- html单页面原理,HTML5单页面手势滑屏切换原理分析
H5现在可谓也是编程世界的主流,H5单页面手势滑屏切换是采用HTML5 触摸事件(Touch) 和 CSS3动画(Transform,Transition)来实现的,下面通过本文简单说一下其实现原理和 ...
最新文章
- python培训班时间 费用-python培训班费用在多少?
- 牛顿插值多项式(python实现)
- 谈谈.NET Core IServiceProvider
- mysql导入数据提前修改字段_Mysql一些导入导出数据库,添加修改字段命令_MySQL...
- 西门子scl语言编程手册_西门子SCL编程PEEK指令讲解
- inotify和epoll
- phpMyAdmin ‘tbl_gis_visualization.php’多个跨站脚本漏洞
- java rmi 多ip_在rmi连接中客户端指定一个ip地址,但程序执行中却转换成另一个地址...
- python setattr 代码可读性_python __setattr__、__getattr__、__getattribute__全面详解
- postman本地访问https
- iOS 常用到的宏#define
- 销售管理系统java sql_java+sqlserver商品销售管理系统的设计与实现
- ActiveMQ下载与安装使用
- 玩手游神助攻:盘点那些具有游戏宏按键,可自定义按键一键多用的模拟器
- 最长回文子串——马拉车算法详解
- DSB算法C语言程序,单片机中使用DSB温度传感器C语言程序.doc
- 计算机设计辅助 CAD 试题汇编,计算机辅助设计试题汇编-第二单元
- 惠普喷墨打印机卡纸了
- 2、Docker安装
- [USACO2.1]健康的荷斯坦奶牛 Healthy Holsteins