안녕하세요 찐망고입니다.
저번 포스팅엔 기본슬라이드에서 버튼을 눌렀을 때 fade효과가 나오는 슬라이드를 만들어 보았는데요
무한슬라이드는
loop의 형태를 false에서 true로 변경해 주면 됩니다.
슬라이드가 loop형태로 바뀌면 슬라이드가 무한 반복되도록 복제된 슬라이드가 추가되어,
실제슬라이더의 인덱스 위치가 바뀌므로
realIndex대신 activeIndex를 사용해야 합니다.
그렇다고 이전 코드에서 저 문구만 바꾸면 에러 메시지가 뜨는데
techSwiper가 선언되기 전에 접근하기 때문이죠.
그래서 swiper를 먼저 선언하고 techSwiper.on('slideChange')를 이용하여 이벤트로 지정하고
탭버튼을 눌렀을 때의 index 위치를 맞춰주기 위해
아래 두 코드를 수정해 줍니다.
// 루프된 슬라이드와 일치하는 실제 슬라이드의 인덱스 가져오기
const targetSlideIndex = Array.from(document.querySelectorAll('.tech-slider .swiper-slide'))
.find(slide => slide.getAttribute('data-swiper-slide-index') == index)
.getAttribute('data-swiper-slide-index');
// 100ms 후에 해당 슬라이드를 변경하고 fade-in 처리
setTimeout(() => {
techSwiper.slideToLoop(targetSlideIndex, 0); // 무한 슬라이드를 위한 slideToLoop 사용
const nextSlide = document.querySelector('.tech-slider .swiper-slide[data-swiper-slide-index="' + targetSlideIndex + '"]');
nextSlide.classList.add('fade-in');
추가적으로 수정해 본 코드는 setTimeout인데
너무 짧은 시간에 여러 번 호출하는 것보다 한 번의 애니메이션 루프에서
여러 작업을 동시에 처리하는 방식으로 최적화하는 게 좋을 것 같아 requestAnimationFrame으로 코드를 수정해 봅니다.
이전 코드는 CSS애니메이션과 별개로 동작해서 슬라이드가 이동하기 전 또는 후에 시간을 지연시키는 역할만 했는데요.
이 방법은 애니메이션 완료타이밍을 CSS에서 관리하므로 setTimeout을 사용할 필요가 없죠.
// 현재 슬라이드에 fade-out 애니메이션 적용
currentSlide.classList.add('fade-out');
// 애니메이션 완료 후 클래스 제거 (fade-out 끝나면 이벤트 발생)
currentSlide.addEventListener('animationend', function handleFadeOut() {
currentSlide.classList.remove('fade-out');
currentSlide.removeEventListener('animationend', handleFadeOut); // 이벤트 리스너 제거
});
// requestAnimationFrame을 사용해 슬라이드를 최적화된 방식으로 이동
requestAnimationFrame(() => {
techSwiper.slideToLoop(targetSlideIndex, 0); // 슬라이드 이동
// 다음 슬라이드에 fade-in 애니메이션 적용
const nextSlide = document.querySelector('.tech-slider .swiper-slide[data-swiper-slide-index="' + targetSlideIndex + '"]');
nextSlide.classList.add('fade-in');
// 애니메이션 완료 후 클래스 제거 (fade-in 끝나면 이벤트 발생)
nextSlide.addEventListener('animationend', function handleFadeIn() {
nextSlide.classList.remove('fade-in');
nextSlide.removeEventListener('animationend', handleFadeIn); // 이벤트 리스너 제거
});
});
}
전체코드
// 탭 슬라이더 설정
const tabSwiper = new Swiper('.tab-slider', {
slidesPerView: 'auto', // 탭 슬라이더 자동 크기 설정
});
// 콘텐츠 슬라이더 설정을 먼저 선언해서 참조 에러 방지
let techSwiper = new Swiper('.tech-slider', {
loop: true, // loop 기능 활성화
effect: 'slide', // fade 효과 사용
});
// fade 효과를 위한 CSS 클래스 추가 및 제거
function fadeInOutContent(index) {
const currentSlide = document.querySelector('.tech-slider .swiper-slide-active');
// 루프된 슬라이드와 일치하는 실제 슬라이드의 인덱스 가져오기
const targetSlideIndex = Array.from(document.querySelectorAll('.tech-slider .swiper-slide'))
.find(slide => slide.getAttribute('data-swiper-slide-index') == index)
.getAttribute('data-swiper-slide-index');
// 현재 슬라이드에 fade-out 애니메이션 적용
currentSlide.classList.add('fade-out');
// 애니메이션 완료 후 클래스 제거 (fade-out 끝나면 이벤트 발생)
currentSlide.addEventListener('animationend', function handleFadeOut() {
currentSlide.classList.remove('fade-out');
currentSlide.removeEventListener('animationend', handleFadeOut); // 이벤트 리스너 제거
});
// requestAnimationFrame을 사용해 슬라이드를 최적화된 방식으로 이동
requestAnimationFrame(() => {
techSwiper.slideToLoop(targetSlideIndex, 0); // 슬라이드 이동
// 다음 슬라이드에 fade-in 애니메이션 적용
const nextSlide = document.querySelector('.tech-slider .swiper-slide[data-swiper-slide-index="' + targetSlideIndex + '"]');
nextSlide.classList.add('fade-in');
// 애니메이션 완료 후 클래스 제거 (fade-in 끝나면 이벤트 발생)
nextSlide.addEventListener('animationend', function handleFadeIn() {
nextSlide.classList.remove('fade-in');
nextSlide.removeEventListener('animationend', handleFadeIn); // 이벤트 리스너 제거
});
});
}
// 슬라이더 초기화가 완료된 후에 slideChange 이벤트 설정
techSwiper.on('slideChange', function () {
const activeIndex = techSwiper.realIndex; // loop에서는 realIndex 사용
document.querySelectorAll('.tab-btn').forEach((tab, index) => {
if (index === activeIndex) {
tab.classList.add('active');
} else {
tab.classList.remove('active');
}
});
});
// 탭 클릭 시 fade 효과 적용
document.querySelectorAll('.tab-btn').forEach((tab, index) => {
tab.addEventListener('click', function () {
// 현재 활성화된 버튼과 동일한 버튼을 클릭한 경우에는 fade 처리하지 않음
if (!tab.classList.contains('active')) {
fadeInOutContent(index); // 탭 클릭 시 fade 효과 적용
}
});
});
아래 코드펜에서 확인해 보세요~
See the Pen swiper무한슬라이드와fade버튼 by 찐망고 (@nnwbliyz-the-styleful) on CodePen.
'플러그인 > swiper' 카테고리의 다른 글
Swiper 슬라이더와 탭 연동하기, loop해결 (0) | 2024.10.28 |
---|---|
Swiper Fraction 페이지네이션에 0 붙이기 (0) | 2024.09.23 |
swiper effect) fade와 slide동시에 구현하기 (0) | 2024.09.11 |
Swiper로 만드는 반응형 탭 인터페이스 - 구루미비즈 예제 (0) | 2024.06.04 |
swiper pagination 2개 연동 - controller 적용 (0) | 2024.03.14 |