[팀 프로젝트] html, css, js로 전체 화면 캐러셀 구현하기

liinyeye·2024년 4월 19일
1

Project

목록 보기
3/44

현재 상황

팀과 팀원을 소개하는 미니 프로젝트를 진행 중이다. 레이아웃이 백프로 마음에 들지는 않았지만, 메인 화면 텍스트 레이아웃에 대해서 충분히 고민할 시간은 없어 일단 그대로 진행하기로 결정했다. 일단 내가 맡은 부분은 상세페이지 구현이었는데, 레이아웃까지는 익숙한 코드라 무리없이 잘 만들었지만 아직 자바스크립트가 익숙치 않아 어떻게 시작해야할지 막막했다.

메인페이지 1 메인페이지 2

상세페이지

문제점

이번에 캐러셀을 처음 구현해보는거라 보통 캐러셀을 구현할 때 이미지 단위로 슬라이드를 넘기는데, 디자인과 기획 상 전체 화면이 넘어가는 방식으로 캐러셀을 구현해야 했다. 처음에는 html 파일을 여러 개를 만들어 버튼을 누르면 다른 html 파일로 넘어가도록 해야하나했는데, 팀원들과 논의 해보니 이미지처럼 div 여러 종류를 만들어 그게 화면에서 슬라이드 되도록 구현하기로 정했다.

일단 구글링해서 찾은 기존 캐러셀 구현하는 방식대로 버튼을 누르면 x축으로 화면 너비만큼 이동하게끔 코드를 짜봤는데, 화면 넘어가는게 매끄럽지 않았다. 또한 캐러셀을 넘기면서 캐러셀 순서에 맞게 아이콘이랑 프로필 배경 이미지도 바뀌어야 하는데, 이 부분 코드를 어떻게 동작시켜야할지 난감했다.

const prevBtn = document.querySelector(".prev");
const nextBtn = document.querySelector(".next");
const carouselSlide = document.querySelector(".carousel-slide");
const carousel = document.querySelectorAll(".carousel");

let index = 0;
const itemNumbers = carousel.length;
// 캐러셀 아이템 갯수 지정

function clickPrevBtn(e){
    if (index === 0) {
        return;
    } else if (index -= 1) {
        carouselSlide.style.transform = `translateX(-100vw)`;
    }
}

function clickNextBtn() {
    if (index === itemNumbers - 1) {
        return;
    } else if (index += 1) {
        carouselSlide.style.transform = `translateX(100vw)`;
    }
}

prevBtn.addEventListener("click", clickPrevBtn);
nextBtn.addEventListener("click", clickNextBtn);

해결 방법

일단 더 코딩을 잘 하시는 다른 팀원분이 코드를 짜주셨다. 앞뒤로 버튼을 움직이면서 캐러셀이 무한히 움직이도록 캐러셀을 원래보다 앞 뒤로 하나씩 더 추가한 부분을 확인할 수 있었다.

HTML 코드

(.carousel-box div안의 내용은 너무 길어 생략)

[전체 구조]

버튼과 캐러셀을 감아주는 .wrapper div

-> 앞, 뒤 button & carousel wrapper로서의 div

-> carousel을 여러 개 담을 .carousel-container div

-> 개별 .carousel-box div__

 <body>
    <div class="wrapper">
      <button class="prev" type="button">
        <i class="fa-solid fa-caret-left fa-2x"></i>
      </button>
        <!--Carousel-->
        <div style="overflow: hidden">
          <div class="carousel-container">
            <!--무한히 움직일 수 있도록 마지막꺼 맨앞으로(편법임)-->
            <div class="carousel-box"><div>
            <div class="carousel-box"><div>
            <div class="carousel-box"><div>
            <div class="carousel-box"><div>
            <div class="carousel-box"><div>
            <div class="carousel-box"><div>
            <!--무한히 움직일 수 있도록 마지막꺼 맨앞으로(편법임)-->
            <div class="carousel-box"><div>
          </div>
        </div>
      <button class="next" type="button">
        <i class="fa-solid fa-caret-right fa-2x"></i>
      </button>
    </div>

JS 코드

    <!--Carousel-->
    <script>
      const carousel = document.querySelector(".carousel-container");
      const carouselBox = document.querySelectorAll(".carousel-box");
      const icons = document.querySelectorAll(".icons");
      const icon = document.querySelectorAll(".icon");
      const nextBtn = document.querySelector(".next");
      const prevBtn = document.querySelector(".prev");

      // 원하는 배경색 헥스코드로 넣기
      const myBackGroundColor = [
        "#618a58", // 홍유나
        "#8fbcdb", // 이준혁
        "#bba2fe", // 복예린
        "#e2c881", // 김승회
        "#288292", // 채종민
      ];

      let idx = 1;
      //함수에서 인자로 boolean을 사용하기 위해 변수를 지정해준다.
      let isInteraction = false;

      const setTransition = (value) => {
        carousel.style.transition = value;
      };

      const setTranslate = () => {
        carousel.style.transform =
          "translateX(" + (-100 / carouselBox.length) * idx + "%)";
      };

      const setBackGroundColor = () => {
        const myIcon = icons[idx].getElementsByClassName("icon")[idx - 1];
        // const myBgColor = bgColors[idx].getElementsByClassName("left-left")[idx - 1];
        // myBgColor.style.backgroundColor = myBackGroundColor[idx - 1];
        myIcon.style.backgroundColor = myBackGroundColor[idx - 1];
        myIcon.style.boxShadow = "0px 0px 10px 5px rgba(0, 0, 0, 0.15)";
      };

      const interaction = () => {
        isInteraction = true;
        setTimeout(() => {
          isInteraction = false;
        }, 600);
      };

      /** 버튼 클릭 시 슬라이드 되는 스타일 변경을 담당 */
      const slide = (idx) => {
        interaction();
        setTransition("300ms all ease-in");

        setTimeout(() => {
          setTransition("");
        }, 300);

        setTranslate();
      };



      const init = () => {
        setBackGroundColor();
        setTranslate();
      };

      init();

      icon.forEach(icon => {
        icon.addEventListener("click", function(e) {
            let parent = e.currentTarget.parentElement;
            let children = parent.children;
            let index = Array.prototype.indexOf.call(children, e.currentTarget) + 1;
            if(idx !== index){
                idx = index;
                slide(idx);
                setBackGroundColor();
            }
        });
      });

      nextBtn.addEventListener("click", () => {
        if (isInteraction) return;
        if (idx >= carouselBox.length - 1) idx = -1;
        idx++;
        slide(idx);

        if (idx === 6) {
          idx = 1;

          setTransition("300ms all ease-in");
          setTimeout(() => {
            setTransition("");
            setTranslate();
          }, 300);
        }
        setBackGroundColor();
      });

      prevBtn.addEventListener("click", () => {
        if (isInteraction) return;
        if (idx <= 0) idx = carouselBox.length;
        idx--;
        slide(idx);

        if (idx === 0) {
          idx = 5;

          setTransition("300ms all ease-in");
          setTimeout(() => {
            setTransition("");
            setTranslate();
          }, 300);
        }
        setBackGroundColor();
      });
    </script>```

느낀점

js 동작 코드에서 캐러셀 버튼을 누르면 어떤 변화가 생겨야하는지 대략 이해는 가는데, 아직 화살표 함수와 다양하게 함수를 정의하고 사용하는 방법에 익숙하지 않아 코드를 봐도 어떤 방식으로 돌아가는지 잘 이해가 되지 않았다.

일단 자바스크립트 강의 복습이랑 추가로 ES6 강의를 듣고 개념을 이해하는 것부터 더 필요할 것 같다.

profile
웹 프론트엔드 UXUI

0개의 댓글