HTML5 단일 페이지에서 제스처 슬라이딩 화면 전환 원리 분석

小云云
풀어 주다: 2017-12-08 09:10:49
원래의
1785명이 탐색했습니다.

H5는 이제 프로그래밍 세계에서도 주류입니다. H5 단일 페이지 제스처 슬라이딩 화면 전환은 HTML5 터치 이벤트(Touch)와 CSS3 애니메이션(Transform, Transition)을 사용하여 구현됩니다. 이를 통해 구현 원리와 주요 아이디어에 대해 간략하게 이야기하겠습니다. 기사가 모두에게 도움이 되기를 바랍니다.

1. 구현 원칙

페이지가 5개이고 각 페이지가 화면 너비의 100%를 차지한다고 가정한 다음 p 컨테이너 뷰포트를 만들고 너비(너비)를 500%로 설정한 다음 로드합니다. 5페이지를 컨테이너에 넣고 이 5페이지가 전체 컨테이너를 균등하게 나누도록 합니다. 마지막으로 컨테이너의 기본 위치를 0으로 설정하고 오버플로를 숨김으로 설정하여 화면에 기본적으로 첫 번째 페이지가 표시되도록 합니다.

<p id="viewport" class="viewport">
    <p class="pageview" style="background: #3b76c0" >
        <h3 >页面-1</h3>
    </p>
    <p class="pageview" style="background: #58c03b;">
        <h3>页面-2</h3>
    </p>
    <p class="pageview" style="background: #c03b25;">
        <h3>页面-3</h3>
    </p>
    <p class="pageview" style="background: #e0a718;">
        <h3>页面-4</h3>
    </p>
    <p class="pageview" style="background: #c03eac;">
        <h3>页面-5</h3>
    </p>
</p>
로그인 후 복사

CSS 스타일:

.viewport{
   width: 500%;
   height: 100%;
   display: -webkit-box;
   overflow: hidden;
   //pointer-events: none; //这句话会导致整个页面上的点击事件失效,如需绑定点击事件,请注掉
   -webkit-transform: translate3d(0,0,0);
   backface-visibility: hidden;
   position: relative;
}
로그인 후 복사

터치스타트, 터치무브, 터치엔드 이벤트를 등록하세요. 화면에서 손가락이 미끄러질 때 CSS3 변환을 사용하여 실시간으로 뷰포트의 위치를 ​​설정하세요. 두 번째 페이지를 표시하려면 뷰포트의 변환(translate3d(100%,0,0))을 설정하기만 하면 됩니다. 여기서는translateX 대신에translate3d를 사용하여 모바일 전화기의 GPU를 활성화하여 렌더링을 가속화하여 페이지 슬라이드를 더 부드럽게 만들 수 있습니다. .

2. 주요 아이디어

화면에 손가락을 대는 것부터 슬라이딩 작업, 화면을 떠나는 것까지 해당 작업이 다음 이벤트를 트리거합니다.

손가락을 댑니다. 화면에서: ontouchstart

화면에서 손가락 슬라이드: ontouchmove

손가락이 화면에서 떠남: ontouchend

페이지 슬라이딩을 완료하려면 터치 이벤트의 세 단계를 캡처해야 합니다.

ontouchstart: 초기화 변수, 손가락 위치 기록, 현재 시간 기록

/*手指放在屏幕上*/
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: 현재 위치를 가져오고 화면에서 손가락 움직임의 차이 deltaX를 계산한 다음 페이지가 움직임을 따르도록 만듭니다

/*手指在屏幕上滑动,页面跟随手指移动*/
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: 손가락이 화면을 떠날 때 화면이 최종적으로 머무는 위치를 계산합니다. 한 페이지. 먼저 화면에서 손가락의 체류 시간 deltaT를 계산합니다. deltaT<300ms인 경우 빠른 슬라이드로 간주됩니다. 반대로 빠른 슬라이드와 느린 슬라이드의 처리는 다릅니다.

빠른 슬라이드입니다. 현재 페이지가 화면 중앙에 완전히 머물도록 하세요. (현재 페이지에서 얼마나 슬라이드해야 하는지 계산해야 합니다.)

느린 슬라이드인 경우 거리도 판단해야 합니다. 화면에서 손가락이 미끄러지는 거리가 화면 너비의 50%를 초과하지 않으면 이전 페이지로 돌아가려면 반대로 현재 페이지에 머물러 있어야 합니다

/*手指离开屏幕时,计算最终需要停留在哪一页*/
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 == &#39;left&#39;?
            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 == &#39;left&#39;?
                currentPosition-(pageWidth+moveLength):currentPosition+pageWidth-moveLength;
                translate = translate > 0 ? 0 : translate;
                translate = translate < maxWidth ? maxWidth : translate;
            }
        }
        //执行滑动,让页面完整的显示到屏幕上
        this.transform.call(viewport,translate);
    }
}.bind(this),false);
로그인 후 복사

현재 페이지가 어느 페이지인지 계산하고 현재 페이지 번호를 설정해야 합니다

//计算当前的页码
pageNow = Math.round(Math.abs(translate) / pageWidth) + 1;
 
setTimeout(function(){
    //设置页码,DOM操作需要放到子线程中,否则会出现卡顿
    this.setPageNow();
}.bind(this),100);
로그인 후 복사

기본 사항입니다. 물론 실제 작업 중에 주의해야 할 몇 가지 세부 사항이 있습니다. 여기서는 자세히 다루지 않겠습니다. 모두 코드에 반영되어 있습니다.

관련 추천:

javascript - 내 주문 페이지가 느리게 로드됩니다

php 단순 페이지 캐싱 구현 코드

Zhihu 단일 페이지를 캡처하는 Python 크롤러 베타 버전

위 내용은 HTML5 단일 페이지에서 제스처 슬라이딩 화면 전환 원리 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!