안녕하세요 찐망고입니다.
저번 포스팅엔 기본슬라이드에서 버튼을 눌렀을 때 fade효과가 나오는 슬라이드를 만들어 보았는데요
swiper effect) fade와 slide동시에 구현하기
안녕하세요 찐망고입니다.오래간만에 swiper 관련 포스팅을 하네요.생각보다 고민을 많이 한 코드라 공유하고자 같이 포스팅해봅니다 클론 한 사이트는 노보셀바이오입니다.http://novocellbio.com/
uiweb.tistory.com
무한슬라이드는
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 |