본문 바로가기

자바스크립트/library

SwiperSlide에 이미지나 영상을 넣었을 때 여백이 발생하는 문제 해결 방법

Swiper 라이브러리를 이용하면 슬라이더를 쉽게 구현할 수 있다.

여기에서 어떤 게 되는지 확인해보자.

 

Swiper라는 컴포넌트를 부모로 하고 SwiperSlide를 여럿 자식으로 넣어 슬라이드 되게 한다.

그러나 SwiperSlide에 이미지나 동영상을 넣었을 경우 ios 모바일에서 오른쪽 패딩이 생기는 문제가 발생했다.

화면당 하나가 오도록 설정했고 (slidePerView = 1) 이대로라면 하나의 SwiperSlide가 뷰포트의 width를 꽉 채워야만 하는데 말이다.

 

문제는 SwiperSlide의 width를 계산하는 로직에 있었다.

실험해보니 브라우저의 viewport가 resize될 때 SwiperSlide width의 CSS 값을 변경하는 것을 확인했다.

이미지나 영상을 다 다운 받기 전에 브라우저가 뷰를 한 번 그리고

다운이 끝나고 다시 뷰를 그려야 하는데 이런 중첩 계산 중에 문제가 발생하는 것으로 보인다.

 

그러므로 이미지와 영상 다운로드가 완료됐을 때 다시 SwiperSlide의 width를 다시 계산 해야 한다.

실제로 브라우저의 크기를 바꾸면 width가 제대로 계산되고 이미지가 viewport width에 딱 맞게 되는 것을 확인했다.

 

이 실험을 토대로 이미지와 영상의 loading이 완료됐을 때 resize 이벤트가 호출되는 로직을 넣었더니 간혹 발생하던 이 문제가 잘 해결되었다.

 

// 이미지의 경우

const handleLoad = () => {
  // window resize 이벤트 호출
  window.dispatchEvent(new Event('resize'));
};

/* ... */

<Image
  // 이미지 로드가 끝났을 때 호출
  onLoad={handleLoad}
/>

 

// 영상의 경우

const handleLoadedData = () => {
  // window resize 이벤트 호출
  window.dispatchEvent(new Event('resize'));
};

/* ... */

<video
  autoPlay
  muted
  loop
  // ios mobile 버그 방지
  playsInline
  // 비디오 로드가 끝났을 때 호출
  onLoadedData={handleLoadedData}
>
  <source src="..." />
</video>

 

도움 받은 글

https://github.com/nolimits4web/swiper/issues/2218#issuecomment-388837042

 

참고로 모바일 ios에서 video가 제대로 동작하려면 playsInline을 넣어야 한다.

https://stackoverflow.com/questions/43570460/html5-video-autoplay-on-iphone

 

dispatchEvent가 궁금하다면

https://ko.javascript.info/dispatch-events