Home > Article > Web Front-end > Detailed explanation of the principle of javascript single page gesture sliding screen switching_javascript skills
H5 single-page gesture sliding screen switching is implemented using HTML5 touch events (Touch) and CSS3 animations (Transform, Transition). The renderings are as shown below. This article briefly talks about its implementation principles and main ideas.
1. Implementation principle
Assume there are 5 pages, each page occupies 100% of the screen width, then create a DIV container viewport, set its width (width) to 500%, then load 5 pages into the container, and let these 5 The entire container is equally divided into two pages. Finally, the default position of the container is set to 0 and the overflow is set to hidden, so that the screen displays the first page by default.
<div id="viewport" class="viewport"> <div class="pageview" style="background: #3b76c0" > <h3 >页面-1</h3> </div> <div class="pageview" style="background: #58c03b;"> <h3>页面-2</h3> </div> <div class="pageview" style="background: #c03b25;"> <h3>页面-3</h3> </div> <div class="pageview" style="background: #e0a718;"> <h3>页面-4</h3> </div> <div class="pageview" style="background: #c03eac;"> <h3>页面-5</h3> </div> </div>
CSS style:
.viewport{ width: 500%; height: 100%; display: -webkit-box; overflow: hidden; pointer-events: none; -webkit-transform: translate3d(0,0,0); backface-visibility: hidden; position: relative; }
Register touchstart, touchmove and touchend events. When your finger slides on the screen, use CSS3 transform to set the position of the viewport in real time. For example, to display the second page, set the viewport's transform: translate3d(100%,0 ,0) That’s it. Here we use translate3d instead of translateX. translate3d can actively turn on the mobile phone’s GPU to accelerate rendering, making the page slide more smoothly.
2. Main ideas
It is a complete operation process from placing your finger on the screen, sliding operation, and then leaving the screen. The corresponding operation will trigger the following events:
Place your finger on the screen: ontouchstart
Finger sliding on the screen: ontouchmove
Finger off the screen: ontouchend
We need to capture these three stages of touch events to complete the sliding of the page:
ontouchstart: Initialize variables, record the location of the finger, and record the current time
/*手指放在屏幕上*/ document.addEventListener("touchstart",function(e){ e.preventDefault(); var touch = e.touches[0]; startX = touch.pageX; startY = touch.pageY; initialPos = currentPosition; //本次滑动前的初始位置 viewport.style.webkitTransition = ""; //取消动画效果 startT = new Date().getTime(); //记录手指按下的开始时间 isMove = false; //是否产生滑动 }.bind(this),false);
ontouchmove: Get the current position, calculate the difference deltaX of the finger movement on the screen, and then make the page follow the movement
/*手指在屏幕上滑动,页面跟随手指移动*/ document.addEventListener("touchmove",function(e){ e.preventDefault(); var touch = e.touches[0]; var deltaX = touch.pageX - startX; var deltaY = touch.pageY - startY; //如果X方向上的位移大于Y方向,则认为是左右滑动 if (Math.abs(deltaX) > Math.abs(deltaY)){ moveLength = deltaX; var translate = initialPos + deltaX; //当前需要移动到的位置 //如果translate>0 或 < maxWidth,则表示页面超出边界 if (translate <=0 && translate >= maxWidth){ //移动页面 this.transform.call(viewport,translate); isMove = true; } direction = deltaX>0?"right":"left"; //判断手指滑动的方向 } }.bind(this),false);
ontouchend: When the finger leaves the screen, calculate which page the screen ends up on. First, calculate the dwell time deltaT of the finger on the screen. If deltaT<300ms, it is considered a fast sliding, otherwise it is a slow sliding. The processing of fast sliding and slow sliding is different:
(1) If it is a quick slide, let the current page stay completely in the center of the screen (you need to calculate how much of the current page needs to be slid)
(2) If it is slow sliding, you also need to judge the distance of the finger sliding on the screen. If the sliding distance does not exceed 50% of the screen width, you need to go back to the previous page. Otherwise, you need to stay on the current page.
/*手指离开屏幕时,计算最终需要停留在哪一页*/ document.addEventListener("touchend",function(e){ e.preventDefault(); var translate = 0; //计算手指在屏幕上停留的时间 var deltaT = new Date().getTime() - startT; if (isMove){ //发生了左右滑动 //使用动画过渡让页面滑动到最终的位置 viewport.style.webkitTransition = "0.3s ease -webkit-transform"; if(deltaT < 300){ //如果停留时间小于300ms,则认为是快速滑动,无论滑动距离是多少,都停留到下一页 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){ translate = currentPosition-moveLength; }else{ //如果滑动距离大于屏幕的50%,则滑动到下一页 translate = direction == 'left'? currentPosition-(pageWidth+moveLength):currentPosition+pageWidth-moveLength; translate = translate > 0 ? 0 : translate; translate = translate < maxWidth ? maxWidth : translate; } } //执行滑动,让页面完整的显示到屏幕上 this.transform.call(viewport,translate); } }.bind(this),false);
In addition, it is also necessary to calculate which page the current page is and set the current page number
//计算当前的页码 pageNow = Math.round(Math.abs(translate) / pageWidth) + 1; setTimeout(function(){ //设置页码,DOM操作需要放到子线程中,否则会出现卡顿 this.setPageNow(); }.bind(this),100);
That’s the basic idea. Of course, there are some details that need to be paid attention to during the actual operation. I won’t go into details here. They are all reflected in the code. The source code has been transferred to Git: https:/ /github.com/git-onepixel/guesture, interested students are welcome to discuss together.