본문 바로가기
내일배움캠프/Today I Learned

[TIL 2023.05.31] 순수 자바스크립트로 무한루프 자동 슬라이드 만들기 (GOE's CINEMA)

by 괴코딩 2023. 6. 1.

💻오늘 배운 내용


 

a.cloneNode() a요소를 그대로 복사
           // a.cloneNode(true) a요소에 자식요소까지 모두 복사

a.prepend() a요소의 앞에 추가

setInterval() 웹페이지의 특정 부분을 주기적으로 업데이트해줘야 하거나, 
              어떤 API로 부터 변경된 데이터를 주기적으로 받아와야 하는 경우
              예) 콘솔에 현재 시간을 2초마다 출력

 

❓발생한 이슈/고민


무한루프 하는 자동슬라이드를 만들려고 한다.

  1. 20개의 카드들이 있고 그 앞뒤로 똑같은 20장의 카드를 복사한 뒤,
  2. -방향으로 한장씩 이동하는 애니메이션을 transition과 자바스크립트로 동작하게 한다.
  3. 그리고 기존카드의 마지막 카드가 카드들을 담고 있는 컨테이너의 첫번째에 오는 순간
  4. 슬라이드의 위치가 다시 처음으로 되돌아가는 로직을 만든다면

무한대로 계속 돌아가는 것처럼 보이게 할 수 있을것이다

또한 무한슬라이드를 구현하면 추가로 마우스를 컨테이너 영역에 올렸을때는 슬라이드 정지.

마우스가 영역을 벗어나면 다시 슬라이드가 움직이는 기능도 같이 만들어 볼 것!

 

💡해결과정


 

let cards = document.querySelector('.cards');
let movie = document.querySelectorAll('.movie'); // NodeList를 배열로 변환
let slideCount = movie.length;

makeClone();

function makeClone() {
  for (let i = 0; i < slideCount; i++) {
    let cloneSlide =
      // a.cloneNode() a요소를 그대로 복사
      // a.cloneNode(true) a요소에 자식요소까지 모두 복사
      movie[i].cloneNode(true);
    cloneSlide.classList.add('clone');
    card.appendChild(cloneSlide);
  }
}

 

가장 먼저 for문으로 카드를 복제했다. 그런데 저장을 해도 클론이 기능하지 않았다.

문제는 makeClone 함수가 fetch 요청 이후에 실행되도록 작성되어야 했다.

현재 코드에서는 fetch 요청과 makeClone 함수의 실행 순서가 잘못되어 클론이 추가되지 않는 것.

 

fetch('<https://api.themoviedb.org/3/movie/popular?language=ko&page=1>', options)
  .then((response) => response.json())
  .then((data) => {
    const moviesContainer = document.getElementById('movies');

    while (moviesContainer.firstChild) {
      moviesContainer.removeChild(moviesContainer.firstChild);
    }

    data.results.forEach((movie) => {
      const card = createMovieCard(movie);
      moviesContainer.appendChild(card);
    });
    // 초기 카드 배치
    let cards = document.querySelector('.cards');
    let movie = document.querySelectorAll('.movie'); // NodeList를 배열로 변환
    let slideCount = movie.length;

    function makeClone() {
      for (let i = 0; i < slideCount; i++) {
        let cloneSlide =
          // a.cloneNode() a요소를 그대로 복사
          // a.cloneNode(true) a요소에 자식요소까지 모두 복사
          movie[i].cloneNode(true);
        cloneSlide.classList.add('clone');
        cards.appendChild(cloneSlide);
      }
    }

    makeClone();
  })
  .catch((err) => console.error(err));

 

fetch 안에 이렇게 수정해주니 콘솔에 잘 찍혀서 나왔다.

 

for (let i = slideCount - 1; i >= 0; i--) {
        let cloneSlide = movie[i].cloneNode(true);
        cloneSlide.classList.add('clone');
        cards.prepend(cloneSlide);
      }

 

앞, 뒤로 복제가 되야하니 makeClone함수안에 기존 요소의 앞에 복제된 카드를 형성하는 for문 추가.

복사본을 만든 다음에 전체길이를 구해야헤서

makeClone함수안에 전체너비를 구해서 cards의 너비를 지정하는 함수를 생성

 

function updateWidth() {
  let currentSlides = document.querySelectorAll('.movie');
  let newSlideCount = currentSlides.length;

  let newWidth =
    (slideWidth + slideMargin) * newSlideCount - slideMargin + 'px';
  cards.style.width = newWidth;
}

 

함수 실행은 makeClone 함수안에 updateWidth() 선언

 

[앞클론배열] [기존배열] [뒤클론배열] 의 형태로 카드가 생성되었는데

 

앞의 클론배열의 [0]에서 시작하는 것이 아니라 기존배열의 [0]부터 시작되도록 설정

그런데 생각해보니 앞에는 굳이 필요 없을 것 같아서 삭제했다

 

한장씩 슬라이드 되게 하려면

처음에는 css의 .cards에 바로 transition: left 1s ease-in-out 효과를 추가했으나

왜인지 몰라도 설정한 이동길이만큼 이동 하지않음+점점 속도가 빨라지는 문제가 있어서

 

function moveSlide(num) {
  cards.style.transition = 'left 1s ease-in-out';
  cards.style.left = -num * (slideWidth + slideMargin) + 'px';
  currentIdx = num;
}

 

자바스크립트로 적용해주었더니 잘 작동했다.

 

이제 기존카드의 마지막 카드가 카드들을 담고 있는 컨테이너의 첫번째에 오는 순간 슬라이드의 위치가 다시 처음으로 되돌아가게끔 해야하는데

 

if (currentIdx == slideCount) {
    setTimeout(function () {
      cards.classList.remove('animated');
      cards.style.left = '0px';
      currentIdx = 0;
    }, 500);

    setTimeout(function () {
      cards.classList.add('animated');
    }, 600);
  }

 

현재 입력된 숫자와 슬라이드 카운트가 일치하면 style의 left값이 '0px’이 되는 조건을

moveSlide 함수 안에 추가했다.

 

하지만 어째서인지 적용이 안됨. 뭐가 문제일까

 

 

콘솔로 직어봤더니 slideCount가 0이라서 되돌아가지 않았던것!

 

if (currentIdx == 20)

 

전체 슬라이드 갯수인 20으로 바꿔줬더니 무한루프가 잘 작동하였다.

변수를 이용하지 못한 것은 아쉽다.

slideCount가 왜 0이 되었는지는 다시 고민해봐야 할 것 같다.

 

마지막으로 마우스를 카드에 대면 일시정지. 마우스를 떼면 다시 슬라이드가 재생되는 기능을

addEventListener로 만들어 봤다

 

cards.addEventListener('mouseover', function () {
  stopSlide();
});

cards.addEventListener('mouseout', function () {
  autoSlide();
});

 

🧐궁금점과 부족한 내용


makeClone 함수 호출시점만 해도 slideCount가 20으로 잘 출력되었었는데 어디서부터

이게 0으로 바뀐지 모르겠다.

slideCount가 왜 0이 되었는지는 다시 고민해봐야 할 것 같다.

반응형