이동 단 효과 의 Swiper 상세 설명

9739 단어 이동 단Swiper
앞 에 쓰다
최근 모 바 일 엔 드 를 만 드 는 데 배 고 픈 vue 전단 구성 요소 라 이브 러 리 를 활용 했다.단순히 구성 요소 로 만 사용 하고 싶 지 않 기 때문에 실현 원 리 를 깊이 알 고 싶다.추 후 다른 구성 요소 의 실현 원 리 를 계속 연구 하고 관심 있 는 것 은 주목 할 수 있 습 니 다.

코드 여기 있 습 니 다.
1.설명
부모 용기 오 버 플 로:hidden;,하위 페이지 transform:translateX(-100%);width:100%;
2.핵심 해석
2.1 페이지 초기 화
모든 페이지 가 핸드폰 화면 왼쪽 에 있 는 화면 너비 의 위치 에 있 기 때문에 처음에는 페이지 에 하위 페이지 가 보이 지 않 기 때문에 첫 번 째 단 계 는 표시 할 하위 페이지 를 설정 해 야 합 니 다.기본 적 인 상황 에서 defaultIndex:0

function reInitPages() {
  //            
  // 1.        
  // 2.            noDragWhenSingle = true
  noDrag = children.length === 1 && noDragWhenSingle;

  var aPages = [];
  var intDefaultIndex = Math.floor(defaultIndex);
  var defaultIndex = (intDefaultIndex >= 0 && intDefaultIndex < children.length) 
    ? intDefaultIndex : 0;
  
  //              
  index = defaultIndex;

  children.forEach(function(child, index) {
    aPages.push(child);
    //         class
    child.classList.remove('is-active');

    if (index === defaultIndex) {
      //            class
      child.classList.add('is-active');
    }
  });

  pages = aPages;
}

2.2 용기 슬라이딩 시작(onTouchStart)
낮은 버 전의 안 드 로 이 드 폰 에 event.preventDefault()를 설정 하면 일정한 성능 향상 작용 을 하여 미 끄 러 지 는 것 이 그리 카드 가 아 닙 니 다.
선행 작업:
사용자 가 prevent:true 를 설정 하면 미끄럼 시 기본 행동 을 막 습 니 다
  • 사용자 가 stopPropagation:true 를 설정 하면 미 끄 러 질 때 사건 이 위로 전파 되 는 것 을 막 습 니 다
  • 애니메이션 이 끝나 지 않 으 면 미끄럼 을 막 습 니 다
  • dragging:true 설정,미끄럼 시작사용자 스크롤 을 false 로 설정 합 니 다.
    슬라이딩 시작:
    전역 대상 을 사용 하여 정 보 를 기록 합 니 다.이 정 보 는 다음 과 같 습 니 다.
    
    dragState = {
      startTime      //     
      startLeft      //    X  
      startTop      //    Y  (       viewport pageY)
      startTopAbsolute  //   Y  (        clientY)
      pageWidth      //       
      pageHeight     //        
      prevPage      //      
      dragPage      //     
      nextPage      //      
    };
    
    2.3 용기 슬라이딩(onTouch Move)
    전역 dragState 를 사용 하여 새로운 정 보 를 기록 합 니 다.
    
    dragState = {
      currentLeft     //    X  
      currentTop     //    Y  (       viewport pageY)
      currentTopAbsolute //   Y  (        clientY)
    };
    그러면 우 리 는 시작 과 미끄럼 중의 정 보 를 통 해 무언 가 를 계산 할 수 있다.
    미 끄 러 지 는 수평 변위(offsetLeft=currentLeft-startLeft)
    미 끄 러 지 는 수직 변위(offsetTop=current TopAbsolute-startTopAbsolute)
    사용자 의 자 연 스 러 운 스크롤 인지 여 부 는 사용자 가 swiper 를 미 끄 러 뜨리 려 는 것 이 아니 라 페이지 를 미 끄 러 뜨리 려 는 것 입 니 다.
    
    //   
    // distanceX = Math.abs(offsetLeft);
    // distanceY = Math.abs(offsetTop);
    distanceX < 5 || ( distanceY >= 5 && distanceY >= 1.73 * distanceX )
    
    왼쪽으로 이동 할 지 오른쪽으로 이동 할 지 판단 합 니 다(offset Left<0 왼쪽으로 이동,반대로 오른쪽으로 이동)
    위치 이동 초기 화
    
    //               
    if (dragState.prevPage && towards === 'prev') {
      //               offsetLeft - dragState.pageWidth
      //    offsetLeft      ,   >0
      //        offsetLeft - dragState.pageWidth        ,      
      //                                   
      //     translate        ,             `transition`,      
      //          ,  `transition`,                
      translate(dragState.prevPage, offsetLeft - dragState.pageWidth);
    }
    
    //         
    translate(dragState.dragPage, offsetLeft);
    
    //        
    if (dragState.nextPage && towards === 'next') {
      translate(dragState.nextPage, offsetLeft + dragState.pageWidth);
    }
    
    
    2.4 슬라이딩 종료(onTouchEnd)
    선행 작업:
    미끄럼 중 에 저 희 는 사용자 의 자연 스크롤 userScrolling 인지 실시 간 으로 판단 할 수 있 습 니 다.사용자 가 자 연 스 럽 게 스크롤 하면 swiper 의 미끄럼 정 보 는 계산 하지 않 기 때문에 제거 작업 을 해 야 합 니 다.
    
    dragging = false;
    dragState = {};
    
    물론 userScrolling:false 라면 하위 페이지 를 미 끄 러 뜨리 고 doOnTouchEnd 방법 을 실행 합 니 다.
    tap 이벤트 인지 아 닌 지 판단 하기
    
    //     300ms,click    300ms  
    //             5  
    if (dragDuration < 300) {
      var fireTap = Math.abs(offsetLeft) < 5 && Math.abs(offsetTop < 5);
      if (isNaN(offsetLeft) || isNaN(offsetTop)) {
        fireTap = true;
      }
      if (fireTap) {
        console.log('tap');
      }
    }
    
    방향 을 판단 하 다
    
    //         300ms      ,    
    if (dragDuration < 300 && dragState.currentLeft === undefined) return;
    
    //         300ms               1/2,         
    if (dragDuration < 300 || Math.abs(offsetLeft) > pageWidth / 2) {
      towards = offsetLeft < 0 ? 'next' : 'prev';
    }
    
    //      ,      ,       ,       ,       
    if (!continuous) {
      if ((index === 0 && towards === 'prev') 
        || (index === pageCount - 1 && towards === 'next')) {
        towards = null;
      }
    }
    
    //        2 ,       
    if (children.length < 2) {
      towards = null;
    }
    
    
    애니메이션 실행
    
    //    options   ,     ,        
    function doAnimate(towards, options) {
      if (children.length === 0) return;
      if (!options && children.length < 2) return;
    
      var prevPage, nextPage, currentPage, pageWidth, offsetLeft;
      var pageCount = pages.length;
    
      //      
      if (!options) {
        pageWidth = element.clientWidth;
        currentPage = pages[index];
        prevPage = pages[index - 1];
        nextPage = pages[index + 1];
        if (continuous && pages.length > 1) {
          if (!prevPage) {
            prevPage = pages[pages.length - 1];
          }
    
          if (!nextPage) {
            nextPage = pages[0];
          }
        }
    
        //            
        //     
        //   doOnTouchMove
        //      options                     
        if (prevPage) {
          prevPage.style.display = 'block';
          translate(prevPage, -pageWidth);
        }
    
        if (nextPage) {
          nextPage.style.display = 'block';
          translate(nextPage, pageWidth);
        }
      } else {
        prevPage = options.prevPage;
        currentPage = options.currentPage;
        nextPage = options.nextPage;
        pageWidth = options.pageWidth;
        offsetLeft = options.offsetLeft;
      }
    
      var newIndex;
      var oldPage = children[index];
    
      //            
      if (towards === 'prev') {
        if (index > 0) {
          newIndex = index - 1;
        }
        if (continuous && index === 0) {
          newIndex = pageCount - 1;
        }
      } else if (towards === 'next') {
        if (index < pageCount - 1) {
          newIndex = index + 1;
        }
        if (continuous && index === pageCount - 1) {
          newIndex = 0;
        }
      }
    
      //          
      var callback = function() {
        //            ,    class
        //       
        if (newIndex !== undefined) {
          var newPage = children[newIndex];
          oldPage.classList.remove('is-active');
          newPage.classList.add('is-active');
          index = newIndex
        }
    
        if (isDone) {
          end();
        }
    
        if (prevPage) {
          prevPage.style.display = '';
        }
    
        if (nextPage) {
          nextPage.style.display = '';
        }
      }
    
      setTimeout(function() {
        //     
        if (towards === 'next') {
          isDone = true;
          before(currentPage);
          //        ,     callback
          translate(currentPage, -pageWidth, speed, callback);
          if (nextPage) {
            //         
            translate(nextPage, 0, speed)
          }
        } else if (towards === 'prev') {
          isDone = true;
          before(currentPage);
          translate(currentPage, pageWidth, speed, callback);
          if (prevPage) {
            translate(prevPage, 0, speed);
          }
        } else {
         //             
         isDone = true;
         //            
         //          
         translate(currentPage, 0, speed, callback);
         if (typeof offsetLeft !== 'undefined') {
           if (prevPage && offsetLeft > 0) {
              translate(prevPage, pageWidth * -1, speed);
           }
           if (nextPage && offsetLeft < 0) {
              translate(nextPage, pageWidth, speed);
           }
         } else {
          if (prevPage) {
           translate(prevPage, pageWidth * -1, speed);
          }
    
          if (nextPage) {
           translate(nextPage, pageWidth, speed);
          }
         }
        }
      }, 10);
    }
    ​
    
    
    백업 작업:
    미끄럼 주기 에 저 장 된 상태 정 보 를 삭제 합 니 다.
    
    dragging = false;
    dragState = {};
    
    총결산
    전체적으로 실현 원 리 는 비교적 간단 하 다.미끄럼 시작 은 초기 위 치 를 기록 하고 이전 페이지 와 다음 페이지 가 보 여 줘 야 할 페이지 를 계산한다.미끄럼 중 위 치 를 계산 하고 이전 페이지 의 다음 페이지 의 위 치 를 계산 합 니 다.미끄럼 끝 은 변위 결과 에 따라 해당 하 는 애니메이션 을 실행 합 니 다.
    미끄럼 중 transition 의 효과 가 비어 있 는 것 은 미끄럼 중 이전 페이지 와 다음 페이지 가 과도 존재 로 인해 자 연 스 럽 지 못 하 게 이동 하 는 것 을 방지 하기 위해 미끄럼 이 끝 난 후에 애니메이션 효 과 를 추가 하 는 것 입 니 다.
    이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

    좋은 웹페이지 즐겨찾기