H5 左右滑屏切页原理 您所在的位置:网站首页 向左滑一下屏幕 H5 左右滑屏切页原理

H5 左右滑屏切页原理

2023-12-27 03:43| 来源: 网络整理| 查看: 265

采用HTML5 触摸事件(Touch) 和 CSS3动画(Transform,Transition)来实现的,效果图如下所示,本文简单说一下其实现原理和主要思路。

实现原理

手指在屏幕上滑动时,页面跟随移动

当手指离开屏幕时,计算手指在屏幕上停留的时间

如果停留时间小于300ms,则认为是快速滑动切换,页面切换到下一页

如果停留时间大于300ms,则认为是慢速滑动,慢速滑动按如下规则处理:

如果滑动距离小于屏幕宽度的50%,则回退到上一页

如果滑动距离大于屏幕宽度的50%,则切换到下一页

 对于多手指触摸操作:  

第一个手指触摸时,正常滑动  第二个手指按下时,不做任何响应操作,继续原有的滑动  当任意一个手指离开屏幕时,结束滑动,剩余的手指操作不做任何处理  当第二个手指再次按下时,触发新的滑动开始,但由于获取的是touches[0],因此,第一个手指移动才会引起页面的滑动  支持多手指同时按下时进行滑动

假设有4个页面,每个页面占屏幕100%宽,则创建一个容器,将其宽度(width) 设置为400%,并让这4个页面平分整个容器,最后将容器的默认位置设置为0,overflow设置为hidden,这样屏幕就默认显示第一个页面。

页面-1 页面-2 页面-3 页面-4

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 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

 



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有