본문 바로가기

Javascript

Javascript: slide # 무한 슬라이드

728x90
반응형

Javascript를 이용해서 무한 슬라이드를 구현해보자


HTML

<div class="rank-banner">
  <div class="flex slide-content">
      <img class="rank-img one-rank-img" src="some01">
      <img class="rank-img one-rank-img" src="some02">
      <img class="rank-img one-rank-img" src="some03">
  </div>
</div>

 

CSS

.rank-banner {
  position: relative;
  overflow: hidden;
}

.slide-content {
  position: absolute;
}

 

Javascript

const slideContainer = document.querySelector(".slide-content");        // slide 틀을 잡아줄 container
const containerLength = slideContainer.children.length;
const slideItemWidth = slideContainer.children[0].offsetWidth;
let slideCount = 0;

function slideBanner() {
  const clonedChildren = slideContainer.children;
  slideContainer.style.transition = "1s ease-out";                      // 애니메이션
  slideContainer.style.left = -slideItemWidth * (slideCount) + "px";
  slideCount++;
  if (slideCount % containerLength == 0) {
    for (let i = 0; i < containerLength; i++) {
      slideContainer.append(clonedChildren[i].cloneNode(true));          // 주의 꼭 cloneNode로!
    }
  }
}

slideBanner();
slideContainer.addEventListener("click", slideBanner);

 

구현 원리는 다음과 같다.

slide를 해줄 기본 이미지가 3개라고 가정하면,

slideContainer를 클릭할 때마다

이미지 [1] [2] [3] 을 포함한 slideContainer가 이미지 크기만큼 좌로 이동한다.

마지막 이미지가 다 나와서 공백이 나오기 전에 slideContainer에 해당 태그의 내부 children들을 append한다.

 

이때 주의 할 부분이 slideContainer.append(clonedChilren[i])로 하지 않고

꼭  clonedChilren[i].cloneNode(true)를 이용해야 한다.

for (let i = 0; i < containerLength; i++) {
  slideContainer.append(clonedChildren[i]);
}

이렇게 cloneNode(true)를 하지 않고 HtmlCollection인 clonedChildren의 요소를 하나씩 잡아 넣는 경우,

clonedChildren에서 한번씩 forloop를 돌면서 append 될 때 마다, append 되어 지는 구성 태그가 하나씩 줄어든다.

 

그럼 다음과 같은 undefined가 끼어들어가게 된다.

* slideBanner() 함수를 페이지 렌더시 한번 실행시켜주는 이유

 slideCount를 1로 시작하고 첫 클릭시가 첫 슬라이드 동작으로 하는 경우,

 애니메이션이 두번째 동작부터 작동.

 (이유는.... 아시는 분이 있으면 알려주시면 너무 감사할 것 같습니다.)

 

-> 페이지 렌더시 slideBanner()함수를 바로 불러오고, slideCount는 0으로 시작해서 실질적인 slide 이동은 없도록 구현

 

 

+ setInterval()로 주기적으로 시행되도록

단, 클릭시에는 clearInterval()로  setInterval 이벤트 초기화 후 다시 실행

slideBanner()
let intervalSlideBanner = setInterval(slideBanner, 2000)
slideContainer.addEventListener("click", function () {
  clearInterval(intervalSlideBanner);
  slideBanner();
  intervalSlideBanner = setInterval(slideBanner, 2000)
});
728x90
반응형