H5 左右滑屏切页原理

123 篇文章 2 订阅
订阅专栏

采用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) {
              //最左边是0
              translate = 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

 

java 翻页例子_jsp实现上一页一页翻页功能(示例代码)
weixin_39681171的博客
02-16 4238
前段时间一直忙于期末考试和找实习,好久没写博客了。这段时间做了个小项目,包含了翻页和富文本编辑器ueditor的两个知识点,ueditor玩的还不是很深,打算玩深后再写篇博客。要实现翻页功能,只需要设置一个pageindex即可,然后每次加载页面时通过pageindex去加载数据就行。那么我们可以设置一个隐藏的input框,用于传递pageindex给下个页面。当我们点击上一页的时候,通过js方法...
H5移动端实现左右滑屏切换页面
热门推荐
水冰月的小兔子的博客
01-09 1万+
项目中需要实现的一个需求是顶部有一个tab选择框,点选某一个tab的时候切换页面,并且支持手势滑动,左滑右滑可以同点选tab一样切换页面。 根据项目中选用的ui组件cube-ui为基准查看了一下可实现的方案,比如可以直接用swipe或者是slide实现,但根据之前的实现方案来看,多少都会有些问题,尤其是在页面嵌套了很多层的垂直和水平滚动的情况下,会让滚动很不流畅。 于是选用了移动端的touch事件...
移动端页面上下滑动,大小、透明度的变化视觉差异效果切换页面
羽筠的博客
09-25 8855
移动端页面上下滑动,大小、透明度的变化视觉差异效果切换页面 上滑动进入下一页 , 当前页从 scale=1 放大至 比1的大倍数 ,并且透明度降低至0 ,下一页从 scale=0.1 放大至 scale=1 , 透明度无变化 下滑动进入前一页 , 当前页从 scale=1 缩小至 scale=0.1 ,透明度无变化     ,下一页从 比1的大倍数 缩小至 scale=1 , 透明度从0至1的
H5 项目页面向左滑动展示下一页,向右滑动展示上一页左右滑动需有左右倾斜的动画,第一页不能右滑,最后一页不能左右滑动...
weixin_35756130的博客
01-10 2241
可以使用手势库 (gesture library) 来实现这种效果。在 HTML5 中,有许多现成的库可以使用,如 Hammer.js 和 swipe.js。 在使用这些库时,首先需要在页面上绑定手势事件。比如,使用 Hammer.js 时可以这样绑定: var myElement = document.getElementById('myElement'); var mc = new Hamme...
h5滑动加载一页数据、滑动请求数据、加载一页
柠檬酸
06-09 4039
html <div class="box"> <div class="main_1"></div> </div> js
移动端手机H5网页滑屏效果
05-10
移动端H5滑屏网页,上滑屏,动态翻页,有背景音乐,点击可开关。
移动端H5上下滑屏翻页demo
03-27
移动端H5上下滑屏翻页demo,本人已做优化,直接在分页内添加内容,就可以看到每页翻页的内容,自适应屏幕大小,直接可上项目
HTML5单页面手势滑屏切换原理
09-28
H5单页面手势滑屏切换是采用HTML5 触摸事件(Touch) 和 CSS3动画(Transform,Transition)来实现的,接下来通过本文给大家介绍HTML5单页面手势滑屏切换原理 ,需要的朋友一起学习吧
HTML5单页面手势滑屏切换原理分析
09-27
1. 实现原理: 首先,我们需要一个包含所有页面内容的容器,这个容器通常被赋予ID“viewport”。为了适应屏幕宽度,我们将容器的宽度设置为屏幕宽度的5倍,即100%的5倍。每个页面作为一个独立的`<div>`元素(class=...
全志H5智能狗原理图.zip
04-06
全志H5智能狗原理原理图 系统框架 只有原理
HTML5全屏图文左右滑动切换特效.zip
07-04
HTML5全屏图文左右滑动切换特效是一款基于jQuery HTML5实现的全屏图文切换特效代码。本作品由【A5源码】收集整理,转载请注明出处!
dw在php图片滑动切换效果,超简单的图片左右切换滑动
weixin_42496225的博客
03-27 3308
网上看过很多图片左右切换滑动的效果,不过大都是使用插件实现。插件虽方便,但是对于新手的学习并不是最好的。本文使用jquery这个由原生的JavaScript封装的库,用最简短的代码实现此功能效果预览如下图:代码部分(直接复制代码便可使用,注意对应的图片路径改成自己的图片路径,图片大小建议300*300)html>超简单的图片左右切换滑动varcot=0;//设置一个计数器,初始值为0;作用...
h5、tab图片滚动原生js代码
开心大表哥
09-29 1903
h5、tab图片滚动原生js代码: 1.先看看案例图片; 2.功能:a.点击tab中的款式,图片可以更换.b点击左右按钮图片可以更换,tab中的款式选中对应的。 话不多说,直接上码: html<div id="product-id"> <ul id="style"> <li class="active">大屏单柜</li> <li>A款</li
web及h5上下翻页功能
a_115098的博客
03-08 1853
实现上下翻页效果可以使用轮播图辅助实现,这里使用element-ui,其它插件使用方法类同。 html代码: //:autoplay="false"不自动播放 :loop="false"不循环 direction="vertical"轮播为数值方向 <el-carousel ref="goupdown" height="100%" direction="vertical" :autoplay="false" :loop="false"> <el-carousel-it
css的transition失效,使用js实现页面左右滑动及动画效果
GardJasmin的博客
10-31 1074
css的transition失效,使用js的setInterval实现页面左右滑动及动画效果
关于h5移动端常见问题整理
wh_xmy的博客
09-21 2804
移动端开发要考虑最多的就是兼容性的问题,android和ios的兼容,css3新增属性的兼容以及h5新增标签等使用问题。下面是一些小问题以及解决方案,仅供参考。 【1】.关于样式的总结 1.移动端开发页面会左右晃动,这时候我们需要给外层容器加上overflow-x:hidden。 2.遮罩层下面的内容依然会滑动,这时候我们可以把所有相关事件都...
移动端Web页面常见问题与解决方案(yuyan)
我的博客
05-24 1733
一、meta标签 1、利用meta标签对viewport进行控制 &lt;meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no"/&gt; 如果你不这样的设定的话,那就会使用那个比屏幕宽的默认viewport,也就是说会出现横向滚动条。 Wi...
H5中判断手势左滑右滑
xiaomao_wxj的博客
04-26 2468
vue-touch-events
移动端h5使用elementui走马灯,手指左右滑动切换
我爱学习的博客
02-14 3097
环境: vue框架,h5端,elementUI组件。手指左右滑动可以切换轮播图。
H5单页面手势滑屏切换原理
最新发布
06-09
H5单页面手势滑屏切换可以通过监听触摸事件来实现。一般来说,需要监听touchstart、touchmove和touchend事件。 在touchstart事件中,记录下触摸开始时的位置和时间。在touchmove事件中,记录下当前触摸位置,计算出...

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
写文章

热门文章

  • CSS 设置文字间距 53902
  • 高效制作动画-Adobe Animate CC 42687
  • phpstudy本地搭建域名访问 33825
  • js 动态拼接已有的变量名并调用 25266
  • select下拉框、input输入框在IOS中背景变黑、出现阴影 18489

分类专栏

  • 前端学习 付费 1篇
  • 前端性能优化
  • 浏览器原理
  • javascript 8篇
  • react 9篇
  • 算法 2篇
  • 前端代码规范 2篇
  • typescript 2篇
  • 协议 2篇
  • h5 7篇
  • web安全 2篇
  • bash 1篇
  • 自动化测试 2篇
  • 项目流程 1篇
  • 技术文章 1篇
  • 高并发 1篇
  • 工具 1篇
  • css 1篇
  • phpmyadmin 2篇
  • php 7篇
  • 编辑器 2篇
  • 前端 123篇
  • 前端,thinkphp框架 1篇
  • phpstudy 1篇
  • git 6篇
  • mysql 5篇
  • CI框架 1篇
  • 工具 10篇
  • Sass 2篇
  • bootstrap 1篇
  • css 18篇
  • 原理 2篇
  • 环境搭建 1篇
  • 架构 2篇
  • webpack 10篇

最新评论

  • chrome浏览器自动填充背景色-webkit-autofill

    qq_31008775: 方法2不错简单粗暴

  • CSS 设置文字间距

    橙-极纪元JJY.Cheng: 转载了昂

  • H5 左右滑屏切页原理

    2301_77748723: 为啥用这个我嵌入的超链接无法点击进入 该怎么解决

  • CSS 设置文字间距

    超甜的仙女啊: csstransform失效

  • 两队PK进度条效果

    可502: 请教一下 如果动态根据数据 这个怎么算百分比呀,同问

大家在看

  • Ansible调优之 Pipelining(任务流水线)详解

最新文章

  • 十六进制8位数颜色代码说明
  • antd Tree拖拽位置说明
  • 字节跳动热门的前端开源项目
2024年7篇
2023年12篇
2022年13篇
2021年36篇
2020年20篇
2019年50篇
2018年27篇
2017年18篇
2016年10篇

目录

目录

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

哆哆女性网景起名钢材线材bosskey招商银行朝朝盈免费起店铺店名网冰河追凶正龙拍虎济南起名大明好国舅宝宝起名全攻略起名平仄法则火锅鱼加盟男孩带木字旁起名字给杨姓宝宝起名的bingfengwangzuo免费起名字测量分数英文商标大全广州同志桑拿6.78c起来个商标名姓氏史的女孩起名程姓怎么起名字玉蒲团之玉女心冒险岛取名字免费测名起名开挂是什么意思李国兴昱和煜起名用字哪个好鼠年女娃起名八卦公司起名大全淀粉肠小王子日销售额涨超10倍罗斯否认插足凯特王妃婚姻不负春光新的一天从800个哈欠开始有个姐真把千机伞做出来了国产伟哥去年销售近13亿充个话费竟沦为间接洗钱工具重庆警方辟谣“男子杀人焚尸”男子给前妻转账 现任妻子起诉要回春分繁花正当时呼北高速交通事故已致14人死亡杨洋拄拐现身医院月嫂回应掌掴婴儿是在赶虫子男孩疑遭霸凌 家长讨说法被踢出群因自嘲式简历走红的教授更新简介网友建议重庆地铁不准乘客携带菜筐清明节放假3天调休1天郑州一火锅店爆改成麻辣烫店19岁小伙救下5人后溺亡 多方发声两大学生合买彩票中奖一人不认账张家界的山上“长”满了韩国人?单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#青海通报栏杆断裂小学生跌落住进ICU代拍被何赛飞拿着魔杖追着打315晚会后胖东来又人满为患了当地回应沈阳致3死车祸车主疑毒驾武汉大学樱花即将进入盛花期张立群任西安交通大学校长为江西彩礼“减负”的“试婚人”网友洛杉矶偶遇贾玲倪萍分享减重40斤方法男孩8年未见母亲被告知被遗忘小米汽车超级工厂正式揭幕周杰伦一审败诉网易特朗普谈“凯特王妃P图照”考生莫言也上北大硕士复试名单了妈妈回应孩子在校撞护栏坠楼恒大被罚41.75亿到底怎么缴男子持台球杆殴打2名女店员被抓校方回应护栏损坏小学生课间坠楼外国人感慨凌晨的中国很安全火箭最近9战8胜1负王树国3次鞠躬告别西交大师生房客欠租失踪 房东直发愁萧美琴窜访捷克 外交部回应山西省委原副书记商黎光被逮捕阿根廷将发行1万与2万面值的纸币英国王室又一合照被质疑P图男子被猫抓伤后确诊“猫抓病”

哆哆女性网 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化