Swiper 슬라이드 인덱스 리셋 방법
Swiper(v11) 슬라이더에서 특정 동작 이후에 인덱스를 0으로 되돌려야 했다. 가장 자연스러운 선택은 slideTo(0)이었는데, 의도와 다른 부작용이 따라붙었다.
slideTo(0)이 끌어들인 페이지 스크롤
swiper.slideTo(0);이 호출로 인덱스는 0으로 갔다. 그런데 슬라이더가 뷰포트 밖에 있을 때 페이지가 슬라이더 위치까지 스크롤되는 현상이 같이 일어났다.
처음에는 slideTo 자체가 페이지 스크롤을 일으키는 줄 알았다. 소스를 따라가 보니 slideTo 함수 본체에는 window.scroll()·focus()·scrollIntoView() 같은 호출이 없었다. wrapper 요소의 scrollLeft·scrollTop만 조작한다.
원인은 다른 데 있었다. Swiper의 a11y 모듈이 슬라이드 변경 시 새 active 슬라이드 안의 포커스 가능 요소에 focus()를 옮기는데, 브라우저가 focused element를 자동으로 뷰포트에 노출하는 표준 동작이 같이 트리거된 결과였다. v11에는 이 자동 포커스 이동을 끄는 옵션이 없어서, slideTo 경로 자체를 피해야 했다.
setTranslate + updateActiveIndex로 우회
스크롤 부작용 없이 인덱스만 0으로 맞추고 싶었다. 트랜스폼 위치를 직접 0으로 되돌리고 active index 상태를 따로 갱신하는 방식으로 우회했다.
swiper.setTranslate(0);
swiper.updateActiveIndex(0);이 조합은 슬라이더에 포커스를 옮기지 않으므로 페이지 스크롤이 따라오지 않는다. 다만 updateActiveIndex는 Swiper 공식 API 문서의 Methods 섹션에 노출돼 있지 않은 내부 업데이트 메서드다. 동작은 했지만, 메이저 버전이 올라가면 시그니처가 바뀔 수 있다는 점은 같이 적어뒀다.
두 경로의 차이
페이지 스크롤이 따라붙지 않으면서 슬라이더 인덱스만 0으로 초기화됐다. 둘 다 "인덱스를 0으로 만든다"는 결과는 같다. 차이는 부수효과에 있었다. slideTo 경로는 a11y의 자동 포커스 이동을 끌어들이는 반면, setTranslate + updateActiveIndex 경로는 시각 상태만 되돌리고 포커스를 건드리지 않는다.