최근 캐러셀 구현을 위해 swipe 라이브러리를 사용했다.
내부 동작이 궁금해 swipe 깃허브에서 코드를 보고 간단하게 정리해보았다.
Swipe 라이브러리에는 슬라이드 관리 방식이 크게 2가지가 있다.
모든 슬라이드를 실제 DOM으로 다 만들어서 관리
.swipe-slide DOM으로 존재한다.appendSlide, removeSlide는 DOM을 직접 추가/삭제슬라이드 데이터만 들고 있고
화면에 필요한 일부만 DOM으로 렌더링
일반 슬라이드의 메소드 인터페이스는 manipulation.ts에서 볼 수 있다.
이제 코드를 살펴보자.
addSlide1. loop면 구조 해체
2. index 뒤 슬라이드 전부 잠시 제거
3. 새 슬라이드 삽입
4. 제거했던 슬라이드 다시 붙임
5. 전체 재계산 + loop 복구 + slideTo로 화면유지
// 1. index 이후 슬라이드들을 DOM에서 제거해서 임시 저장
const slidesBuffer = [];
for (let i = baseLength - 1; i >= index; i -= 1) {
const currentSlide = swiper.slides[i];
currentSlide.remove();
slidesBuffer.unshift(currentSlide);
}
// 2. 새 슬라이드를 원하는 위치에 append
slidesEl.append(slides);
// 3. 제거했던 슬라이드들을 다시 뒤에 붙임
for (let i = 0; i < slidesBuffer.length; i += 1) {
slidesEl.append(slidesBuffer[i]);
}
DOM에는 insertBefore 같은 고수준 API를 쓰지 않고 있다.
"뒤쪽 슬라이드 전부 빼고 -> 새 슬라이드 붙이고 -> 다시 붙인다" 전략을 쓰기 때문이다.
Swipe는 내부적으로 슬라이드 순서를 단순하게 slidesEl.children 순서로 관리하기 때문에 중간 삽입을 직접 지원하지 않는다. 그래서 물리적으로 DOM을 재배치하는 방식을 사용하고 있다.
1. loop 모드면 복제 슬라이드 때문에 loop 제거
2. 지정한 인덱스의 슬라이드 DOM 제거
3. activeIndex 보정
4. 슬라이드 목록 재계산
5. loop 복구
6. 화면 유지 (보던 슬라이드로 이동)
loop 모드에서는 앞/뒤에 복제 슬라이드가 붙어서 인덱스가 어긋나기에 loop를 제거한다.
// 1. 슬라이드 DOM 제거
swiper.slides[indexToRemove].remove();
// 2. 삭제로 인해 activeIndex 보정
if (indexToRemove < activeIndex) {
activeIndex -= 1;
}
// 3. 슬라이드 목록 재수집
swiper.recalcSlides();
슬라이드 DOM을 제거하고, 그로 인해 밀린 activeIndex를 보정한 뒤 Swiper가 다시 계산하게 하는 것이다.
이외에도 모든 슬라이드를 제거하는 removeAllSlides가 있다.
1. loop 모드면 기존 loop 구조 제거
2. 슬라이드 DOM 추가
2-1. 문자열 -> 임시 DOM 생성 후 append
2-2. HTMLElement -> 그대로 append
3. 슬라이드 목록 재계산
4. loop 복구
5. 레이아웃과 상태 업데이트
// 1. 슬라이드 DOM에 추가
slidesEl.append(slideEl);
// 2. Swiper 내부 슬라이드 목록 재수집
swiper.recalcSlides();
복잡한 로직은 없었고 슬라이드 DOM 추가 -> Swipe가 변화를 인식하는 것이 다였다.
1. loop 모드면 기존 loop 구조 제거
2. 슬라이드 DOM을 맨 앞에 추가
2-1. 문자열 → 임시 DOM → prepend
2-2. HTMLElement → 그대로 prepend
3. activeIndex 보정 (앞의 슬라이드가 추가되었으므로)
4. 슬라이드 목록 재계산
5. loop 복구
6. 레이아웃과 상태 업데이트
7. 보던 슬라이드로 유지
// 1. 슬라이드를 맨 앞에 DOM으로 추가
slidesEl.prepend(slideEl);
// 2. 앞에 추가됐으므로 activeIndex 보정
newActiveIndex = activeIndex + addedSlidesCount;
// 3. Swiper 내부 상태 재계산
swiper.recalcSlides();
슬라이드를 DOM 앞에 붙이고, activeIndex를 밀어준 뒤 Swipe가 다시 계산하게 한다.
appendSlide → DOM 뒤에 추가
prependSlide → DOM 앞에 추가 + index 밀기
addSlide → DOM 재배치
removeSlide → DOM 제거 + index 당기기
다음글에서는 Virtual 슬라이드 동작과 특징, 그리고 일반 슬라이드와 Virtural 슬라이드의 차이점과 쓰임에 대해 작성해보려 한다.