💬 swiper.js 8.4.7 버전을 기준으로 작성하였습니다.
React.js를 사용하지 않고 그림과 같이 탭 메뉴로 구성된 컨텐츠를 마크업하게 될 경우, 일반적으로 보이지 않는 탭 메뉴를 display: none
처리하여 사용하는 경우가 많을 것입니다.👀
이번에 TypeScript
+ Swiper.js
를 이용하여 위 구조를 만들게 되었는데, swiper 기능은 작동하는데 autoplay(자동 재생)만 되지 않는 이슈가 있었습니다.
// PARAM swiper option
// 공통적으로 사용되는 슬라이드 옵션을 만들었습니다.
const swiperOption: SO = {
speed: 400,
loop: true,
init: true,
effect: 'slide',
autoHeight: true,
};
// FUNCTION swiper init
const swiper = new Swiper('.slide', {
// rest 문법으로 공통으로 사용되는 슬라이드 옵션을 새로 정의할 옵션과 합쳐주었습니다.
...swiperOption,
speed: 700,
autoplay: {
delay: 3500,
disableOnInteraction: false,
},
spaceBetween: 20,
centeredSlides: true,
slidesPerView: 1,
navigation: {
prevEl: document.querySelector('.slide .swiper-button-prev'),
nextEl: document.querySelector('.slide .swiper-button-next'),
},
pagination: {
el: '.swiper-pagination',
clickable: true,
},
breakpoints: {
641: {
slidesPerView: 'auto',
},
},
});
swiper 객체 옵션 속성은 다음과 같았습니다. autoplay
속성을 설정해 주었는데도 자동 재생만 작동되지 않았습니다.
검색을 해 보니, display:none
일 시에는 swiper.js의 autoplay가 제대로 작동하지 않는다고 합니다. (width 계산 문제로 autoplay 작동이 멈추는 것으로 추정됩니다🤔)
observer
속성과 observeParents
속성을 추가하면 Swiper 요소나 부모 요소의 DOM 변경이 감지되었을 경우, Swiper를 자동으로 업데이트(재초기화) 해 준다고 하여 다음 옵션을 추가하였습니다.
const swiperOption: SO = {
observer: true,
observeParents: true,
speed: 400,
loop: true,
init: true,
effect: 'slide',
autoHeight: true,
};
그런데도 자동 재생이 실행되지 않았습니다. 분명 글들에는 전부 다 해당 옵션들을 추가하면 해결된다고 쓰여 있었는데...😇
그래서 슬라이드 강제 업데이트를 실행해 주었습니다.
// FUNCTION swiper restart
const setSwiperStart = (swiper: Swiper) => {
const tab = document.querySelector('.contents--story');
if (tab?.classList.contains('active')) {
swiper.update();
}
};
swiper 객체를 매개변수로 받아 슬라이드가 있는 해당 탭 요소에 active
라는 클래스(display: block
으로 설정해 주는 클래스) 가 있을 경우 업데이트 해 주는 함수를 만들었습니다.
tabList.forEach((el) => {
el.addEventListener('click', onClickTabBtn);
el.addEventListener('click', () => setSwiperStart(swiper));
});
sidebarMenu.forEach((el) => {
el.addEventListener('click', onClickTabBtn);
el.addEventListener('click', () => setSwiperStart(swiper));
});
그리고 탭 메뉴를 전환하는 버튼을 클릭했을 시, 해당 함수를 실행하도록 addEventListner
로 추가해 주었습니다. (지금 보니까.. onClickTabBtn
안에서 호출하는 게 더 깔끔했을 것 같네요😹)
그리고 결과는... 실행되지 않았습니다 💀
뭔가 이상해 함수에console.log(swiper.autoplay);
를 추가해주니 콘솔창에 다음과 같은 Object가 출력되었습니다.
속성명을 보니 왠지 paused
와 running
이 동작 상태 같고,
stop
과 start
는 상태를 전환해 주는 메서드 인 것 같습니다. 그리고 running
이 false
상태네요.
그래서 함수를 다음과 같이 수정해 주었습니다.
// FUNCTION swiper restart
const setSwiperStart = (swiper: Swiper) => {
const tab = document.querySelector('.contents--story');
if (tab?.classList.contains('active')) {
swiper.autoplay.start(); // 추가!
swiper.update();
} else {
swiper.autoplay.pause(); // 추가!
swiper.update();
}
console.log(swiper.autoplay);
};
그런데 이렇게 해도 실행되지 않았습니다.
속성 값을 직접 바꾸는 방법으로 다시 한번 함수를 수정해 주었습니다.
const setSwiperStart = (swiper: Swiper) => {
const tab = document.querySelector('.contents--story');
if (tab?.classList.contains('active')) {
swiper.autoplay.paused = false;
swiper.autoplay.running = true;
} else {
swiper.autoplay.paused = true;
}
console.log(swiper.autoplay);
};
running
속성의 값이 true로 바뀌고 드디어 자동 재생이 되기 시작합니다.😂
observer
와 observeParents
속성을 true로 적용하였는데도 자동 재생이 실행되지 않을 경우, 위와 같은 방법들을 사용해 보는 것도 해결책이 될 수 있을 것 같습니다.