이동 단 효과 의 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 를 설정 하면 미끄럼 시 기본 행동 을 막 습 니 다
슬라이딩 시작:
전역 대상 을 사용 하여 정 보 를 기록 합 니 다.이 정 보 는 다음 과 같 습 니 다.
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 의 효과 가 비어 있 는 것 은 미끄럼 중 이전 페이지 와 다음 페이지 가 과도 존재 로 인해 자 연 스 럽 지 못 하 게 이동 하 는 것 을 방지 하기 위해 미끄럼 이 끝 난 후에 애니메이션 효 과 를 추가 하 는 것 입 니 다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Swiper 내 비게 이 션 바 스크롤 효과 구현일부 모 바 일 앱 에서 네 비게 이 션 표시 줄 이 굴 러 가 는 것 을 볼 수 있 습 니 다.다음 의 예 는 vant 의 공식 문서 에서 볼 수 있 습 니 다.이러한 굴 러 가 는 효 과 는 Swiper 를 이용...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.