[패스트캠퍼스X야놀자 : 프론트엔드 개발 부트캠프] 슬라이더 구현( 설계 과정 )

일단해봐·2023년 7월 28일
0
post-thumbnail

📌 과제 소개

야놀자x패스트캠퍼스 부트캠프 과정 첫 번째 과제로 배운 내용을 바탕하여 원하는 사이트를 선정해 클론 코딩하는 것을 받았다. 내가 선정한 사이트는 패스트캠퍼스 메인 페이지다. 페이지 선정은 자유였으나 패스트캠퍼스에서 진행하는 과정이니 더 재밌는 피드백이 나올 수 있을 것 같아 선정했다.

사진은 클론 코딩 대상인 패스트캠퍼스 메인 페이지고 하단은 구현 중인 클론 페이지다.

아직 상단 배너와 네비게이션 바만 완성한 상태이며 현재 메인 섹션의 슬라이더를 구현하기 위해 구상 중이다.


📌 슬라이더 구현 접근 방식 및 설계

*이 단계는 페이지 구현을 마친 후가 아닌 설계 단계에서 작성되었다.

기능 정리

페이지에 접속해 보면 슬라이더는 총 4가지의 특별한 기능이 설계되어 있다.

  1. 자동으로 초단위로 FadeIn/Out 하는 슬라이드
  2. FadeIn/Out 사이에 이미지를 확대시켜 이미지가 다가오는 느낌 만들기
  3. 슬라이드 갯수와 현재 슬라이드 순서를 나타내는 도트들
  4. 슬라이드를 좌우로 직접 넘기거나 슬라이드가 자동으로 넘어가는 기능을 멈추고 실행하는 버튼

구현 방법 구상

1. 자동으로 초단위로 FadeIn/Out 하는 슬라이드

FadeIn/Out하는 슬라이드는 다른 페이지들에서도 많이 사용되는 슬라이더 방식이다. 아마 이미지와 글이 담긴 여러 개의 a태그들을 position을 absolute로 하여 같은 축에 일렬로 세우고(z축이 같다고 표현해야 하나) 순서에 해당하는 a태그의 display는 block으로 설정하고 나머지는 none으로 설정한 뒤 setinterval() 함수를 이용하여 순서에 맞게 띄워주면 될 것 같다. 그리고 css 속성에 transform 속성을 넣어 적당한 시간을 주어 천천히 사라지고 나타나는 FadeIn/Out 효과를 만들 것 같다.

2. FadeIn/Out 사이에 이미지를 확대시켜 이미지가 다가오는 느낌 만들기
이거는 매우 간단하게 전체 이미지를 감싸는 a태그를 overflow:hidden으로 설정해 안에 들어있는 요소들이 밖으로 나오지 못하게 설정하고 안에 있는 img태그를 시간을 주어 크기를 늘리면 확대되는 느낌을 줄 수 있을 것이다.

3. 슬라이드 갯수와 현재 슬라이드 순서를 나타내는 도트들
이게 제일 어렵다고 느끼는데 클릭에도 반응해야 하고 모양도 radio의 checked 상태도 아닌 특정한 모양을 만들어야 한다. 지금 생각하는 구현 방식은 grid css를 활용하여 원 모양의 도트들을 div 박스에 border-radius 속성을 활용해 만들고 해당 순번의 grid-templete-colums를 다른 도트들보다 2배로 주면 해결되지 않을까 싶다. 아직 grid 속성을 활용해본 적이 없어 확신이 들지 않지만 한 번 시도해봐야겠다. 그리고 내가 모르는 radio 버튼의 스타일 속성을 활용한 방법일 수도 있으니 찾아봐야겠다.

📝 추가로 위치한 도트들을 연속적으로 클릭했을 때 오류가 발생하지 않도록 일정시간의 연속 입력을 하나의 입력으로 처리하는 코드가 있는 것 같은데 이벤트를 그룹화 시켜 연속적인 이벤트 발생을 막는 디바운스를 활용한 게 아닌가 싶다. 아직 구현하기 어렵고 시간도 부족하니 다음에 사이트 기능을 향상시킬 때 도전해봐야겠다.

4. 슬라이드를 좌우로 직접 넘기거나 슬라이드가 자동으로 넘어가는 기능을 멈추고 실행하는 버튼
좌우로 넘어가는 방식은 위 도트 방식과 비슷하게 클릭 시 이벤트가 발생하는 방식으로 구현을 하고 멈추고 실행하는 버튼은 setinterval()함수를 멈추는 함수도 있기 때문에 이를 활요하면 될 것 같다.

5. 마지막으로 예상가는 문제점
모든 기능을 구현해봐야 알겠지만 아마도 스크립트 코드들이 꼬이는 현상이 발생할 것 같다. 슬라이더가 넘어가는 방식이 총 3가지다 보니 setinterval()함수와 엉켜 넘기자 마자 넘어가거나 이상한 곳에 display 값을 none과 block을 주는 문제가 생길 것으로 예상된다.


📌 구현 결과

원본 사이트 : https://fastcampus.co.kr/
클론 사이트 : https://scintillating-kleicha-014b82.netlify.app/#

깃허브 : https://github.com/KDT1-FE/Y_FE_HTML_CSS/pull/48

1. FadeIn/Out

처음엔 display 속성을 none/block으로 전환하여 구현하려고 했으나 transition 속성 값으로 display로 했을 때 잘 구현이 되지 않아 opacity 0/1로 전환하여 구현하니 깔끔하게 구현됐다.

.curation-section__slidelist li{
    opacity: 0;
    transition: opacity 1s ease-out;
    width: 100%;
    position: absolute;
}

2. 확대 기능

확대 기능도 처음 설계한 것처럼 부모 요소에 overflow : hidden을 설정하고 해당 슬라이드가 노출 될 때 scale을 키우는 방식으로 다가오는 느낌을 구현하였다.

.curation-section{
    width: 100%;
    height: 450px;
    overflow: hidden;
    position: relative;
}

.curation-section__slide__img{
    width: 1280px;
    position: absolute;
    top:0;
    z-index: 1;
    transform: scale(1);
    transition: transform 2.5s ease-out;
}

3. 도트들

이번에 처음 input radio타입과 label을 이용하여 슬라이더와 토글들을 구현해보았는데 굉장히 편하고 활용도가 높아 보였다. 예를 들어 이커머스 사이트에서 카테고리를 클릭했을 때 나열되는 상품들이 바뀌게 구현 할 수 있을 것 같다.

설계 단계에선 label에 관한 개념이 없어 radio 버튼을 어떻게 도트처럼 표현할지 고민했지만 label을 활용하여 생각보다 쉽게 구현하였다. flex div에 담아 checked 상태인 label의 크기만 늘려주면 됐다.

.curation-section__radio label{
    display: inline-block;
    width:12px;
    height: 12px;
    margin: 6px;
    border-radius: 6px;
    background-color: rgba(255,255,255,.5);
    transition: width 0.5s;
}

.curation-section [id="slide01"]:checked ~ 
.curation-section__slidewrap 
.curation-section__radio 
label:nth-child(1){
	width: 50px; background-color: #fff;
}

4. 자동으로 넘기는 기능 및 문제 해결

자동으로 넘어가는 기능은 간단하게 slideIndex 변수를 만들어 nth-child(변수) 안에 변수를 넣어 setinterval 함수로 자동으로 5초마다 넘어가게 하였다. 하지만 문제는 계속 slide가 바뀌다 인위적으로 바꿨을 때 slideIndex가 따라오지 못하고 setinterval을 멈췄다 실행하지 못하여 1번에 있다 10번으로 가도 2번으로 넘어가는 문제가 생겼다.

이를 해결하기 위해 인위적으로 checked 값을 옮길 때 slideIndex 값도 변경해야 하고 setinterval 메서드도 멈췄다 다시 실행해야 한다.

그래서 도트를 클릭하여 checked를 옮길 때 'click'이벤트를 감지하여 setInterval() 메서드를 clearInterval()을 통해 한 번 멈춰주고 index값을 다시 재조정 후 자동으로 넘어가게 setInterval()을 다시 실행해주었다.

var slideIndex = 1;

let slideCallback = function(){
  if(slideIndex === 13){
    slideIndex = 1;
  }else{
    slideIndex++;
  }

  const slide = document.querySelector(`.curation-section input:nth-child(${slideIndex})`);
  slide.checked = true;
}

slideinterval = setInterval(slideCallback,5000)


document.addEventListener('DOMContentLoaded', function() {
  var checkboxes = document.querySelectorAll('input[type=radio][name=slide]');

  for (var checkbox of checkboxes)
  {
    checkbox.addEventListener('change', function(event)
                              {
      if (event.target.checked) {
        clearInterval(slideinterval)
        slideIndex = Object.values(checkboxes).indexOf(event.target)+1;
        slideinterval = setInterval(slideCallback,5000)
      }
    });
  }
}, false);

📌 결론

일주일 동안 코딩을 하면서 확실히 예전보다 성장했음을 느낄 수 있었다. 전체적인 웹페이지를 만들어 본 건 그리 오래되지 않았지만 예전엔 서칭을 하면서도 코드 이해하는데 오래 걸리고 머릿속에서 코드들을 추상화 하기도 어려웠는데 확실히 더 수월해진 것 같다.

그리고 무작정 만들기 보다 먼저 설계 단계를 거치고 진행하여 시간도 많이 단축했던 것 같고 완성한 뒤 전의 설계의 문제점을 다시 공부할 수 있고 왜 이런 방법을 택했는지도 더욱 명확해졌다.

지금은 비록 작은 단위의 그리고 클론 코딩의 수준이지만 나중에 더 큰 단위의 프로젝트를 진행할 때는 더욱 설계 단계가 중요하겠다는 생각이 들었다.

결론 : 만족적인 결과물

profile
안녕하세요, 프론트엔드 개발자가 될 열정적인 사람입니다.

0개의 댓글