采用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 左右滑屏切页原理相关推荐

  1. h5实现上下滑动切页

    安卓系统下正常使用,ios系统下无法滑动切页,那位大神可以找到问题,多谢大佬 <!DOCTYPE html> <html lang="en"> <he ...

  2. H5视差滑屏,Swiper的Parallax属性

    参考文档:Swiper中文网-轮播图幻灯片js插件,H5页面前端开发 标准地图来源:自然资源部地图技术审查中心承办的标准地图服务 想要了解和下载更多关于 标准地图 的内容,欢迎访问中国地图出版集团官网 ...

  3. html 滑屏 效果,HTML5 web app实现手动页面滑屏效果

    现在很流行在H5页面滑屏的效果,特别是在微信浏览器窗口中,几乎很多推广的活动是使用到上下滑屏,一开始和前端的同事一起合作写滑屏效果花费了很多的时间,而且写出来的页面在浏览器的兼容上踩了很多坑,于是果断 ...

  4. [重磅] 让HTML5达到原生的体验 系列之中的一个 避免切页白屏

    非常多人都想.甚至曾使用HTML5开发跨平台App.而且想达到原生App的体验. 最后的结果都是无奈的放弃.HTML5貌似美好,但坑太多.想做到原生App的体验差点儿不可为. 也曾有过著名的faceb ...

  5. jsp页面div上下滑动_H5单页面手势滑屏切换原理

    H5单页面手势滑屏切换是采用HTML5 触摸事件(Touch) 和 CSS3动画(Transform,Transition)来实现的,效果图如下所示,本文简单说一下其实现原理和主要思路. 实现原理 假 ...

  6. 提升html5的性能体验系列之一避免切页白屏

    窗体切换白屏的现实问题 HTML5的性能比原生差很多,比如切页时白屏.列表滚动不流畅.下拉刷新和上拉翻页卡顿. 在低端Android手机上,很多原生App常用的功能和体验效果都很难使用HTML5技术模 ...

  7. html5页面图片切换,HTML5单页面手势滑屏切换原理

    H5单页面手势滑屏切换是采用HTML5 触摸事件(Touch) 和 CSS3动画(Transform,Transition)来实现的,效果图如下所示,本文简单说一下其实现原理和主要思路. 1.实现原理 ...

  8. 手机 html5 hammer drag widget,Hammer.js+轮播原理实现简洁的滑屏功能

    最近有个任务,做一个非常小的h5的应用,只有2屏,需要做横向的全屏滑动切换和一些简单的动画效果,之前做这种东西用的是fullpage.js和jquery,性能不是很好,于是就想自己动手弄一个简单的东西 ...

  9. html单页面原理,HTML5单页面手势滑屏切换原理分析

    H5现在可谓也是编程世界的主流,H5单页面手势滑屏切换是采用HTML5 触摸事件(Touch) 和 CSS3动画(Transform,Transition)来实现的,下面通过本文简单说一下其实现原理和 ...

最新文章

  1. python培训班时间 费用-python培训班费用在多少?
  2. 牛顿插值多项式(python实现)
  3. 谈谈.NET Core IServiceProvider
  4. mysql导入数据提前修改字段_Mysql一些导入导出数据库,添加修改字段命令_MySQL...
  5. 西门子scl语言编程手册_西门子SCL编程PEEK指令讲解
  6. inotify和epoll
  7. phpMyAdmin ‘tbl_gis_visualization.php’多个跨站脚本漏洞
  8. java rmi 多ip_在rmi连接中客户端指定一个ip地址,但程序执行中却转换成另一个地址...
  9. python setattr 代码可读性_python __setattr__、__getattr__、__getattribute__全面详解
  10. postman本地访问https
  11. iOS 常用到的宏#define
  12. 销售管理系统java sql_java+sqlserver商品销售管理系统的设计与实现
  13. ActiveMQ下载与安装使用
  14. 玩手游神助攻:盘点那些具有游戏宏按键,可自定义按键一键多用的模拟器
  15. 最长回文子串——马拉车算法详解
  16. DSB算法C语言程序,单片机中使用DSB温度传感器C语言程序.doc
  17. 计算机设计辅助 CAD 试题汇编,计算机辅助设计试题汇编-第二单元
  18. 惠普喷墨打印机卡纸了
  19. 2、Docker安装
  20. [USACO2.1]健康的荷斯坦奶牛 Healthy Holsteins

热门文章

  1. matlab symadd,信号调理器设计—大二暑期信号分析实习报告精选多篇
  2. 笔迹鉴定流程,都需要什么,费用多少?
  3. Selenium元素操作与属性值_Sinno_Song_新浪博客
  4. EasyExcel与POI
  5. AI虚拟模特会被普及吗?
  6. 争创福建省青年文明号
  7. guava之基本工具
  8. PID 控制保姆级培训教程下-全国大学生电子设计大赛赛前必备
  9. 浅谈UML---协作图
  10. 保卫农场(bfs)题解