TIL | 09/21/2022

블로그 이사 완료·2022년 9월 21일
0
post-thumbnail

오늘의 작업물

# 자동슬라이드 배너 자바스크립트 코드 작성하기

1) 크기 및 정렬

.banner_frame {
    position: absolute;
    display: flex;
    justify-content: flex-start;
    width: 1200%;
    height: 100%;
    left: 0;
    transition: left 0.6s linear 0s;
}
.banner_frame > section {
    flex: 1;
    height: 100%;
}

지금 제작하고있는 웹 배너 영역의 가로크기는 화면의 100%다.

배너의 가로크기는 부모인 배너영역의 가로크기를 상속받아 동일하게 화면의 100%다.

베너 프레임(모든 배너를 담은 div태그)의 가로크기는 배너 가로크기 x 배너 개수 가 된다.

정렬은 간단하게 부모인 배너프레임에 display:flex; 선언하고 하위요소인 배너에 flex:1; 을 선언했다.

2) 다음/이전 버튼 클릭 시 슬라이드

let bnnNum = 0;
let lastNum = document.querySelectorAll('.banner_frame>section').length - 1;

초기 카운트 0인 변수와 배너배열의 마지막 인덱스 번호 변수를 생성한다.

let bnnWidth = document.querySelector('body>section').offsetWidth; //section 의 width 값 할당
window.addEventListener('resize', () => {
  bnnWidth = document.querySelector('body>section').offsetWidth; //resize 될 때 width값 재할당
});

배너의 가로 사이즈 변수를 생성한다.(전체일수도, 아닐수도)
이 값은 윈도우 크기가 변경 될 때마다 재할당 되어야 한다.

// next버튼 클릭
btnNext.addEventListener('click', (e) => {
  e.preventDefault();
  bnnNum++;
  if (bnnNum > lastNum) bnnNum = 0;
  bnnAction(bnnNum);
  clearTimeout(autoBnn);
  flag = false;
  bnnPlayBtn.classList.add('on');
});

// preve버튼 클릭
btnPrev.addEventListener('click', (e) => {
  e.preventDefault();
  bnnNum--;
  if (bnnNum < 0) bnnNum = lastNum;
  bnnAction(bnnNum);
  clearTimeout(autoBnn);
  flag = false;
  bnnPlayBtn.classList.add('on');
});

다음버튼을 클릭 시 카운트변수 bnnNum++; 하고, 이전버튼을 클릭 시 카운트변수 bnnNum--; 으로 현재 배너의 번호를 구한다.

증가 혹은 감소 시킨 변수의 값과 배너의 가로 값을 곱한 값을
배너 프레임의 left값으로 지정한다. (강사님은 배너 프레임이라는 기차가 전진한다고 표현하신다.)

// 함수
// left 값 변경하고 클래스 추가/삭제,
// 섹션에 white포함 되어있으면 버튼/롤링에 white클래스 추가
let bnnAction = (bnnNum) => {
  bnnFrame.style.left = `${-bnnNum * bnnWidth}px`;

  bnnRollA.forEach((item) => {
    item.classList.remove('on');
  });
  bnnRollA[bnnNum].classList.add('on');

  if (bnnSection[bnnNum].classList.contains('white')) {
    bnnArrowA.forEach((item) => {
      item.classList.add('white');
    });
    rollingA.forEach((item) => {
      item.classList.add('white');
    });
  } else {
    bnnArrowA.forEach((item) => {
      item.classList.remove('white');
    });
    rollingA.forEach((item) => {
      item.classList.remove('white');
    });
  }
};
// 초기 함수 1회 실행
bnnAction(bnnNum);

위의 bnnAction() 함수 안에 배너프레임의 left값을 변경하는 코드와 현재 배너의 클래스를 변경 시키는 코드를 작성시켜놨다.

또 배너안의 스프라이트 이미지가 배너마다 달라 조건을 붙여 클래스를 변경하는 코드도 있다.

사이트 로드 되고 첫 배너는 함수가 작동 되어야 하므로 초기 1회 실행한다.

3) 오토배너 (자동 슬라이드)

// 오토배너
let autoBanner = () => {
  bnnNum++;
  if (bnnNum > lastNum) bnnNum = 0;
  bnnAction(bnnNum);
  autoBnn = setTimeout(autoBanner, 3000); // 재귀함수로 재실행
};
let autoBnn = setTimeout(autoBanner, 3000); // 함수 최초 실행

일정한 시간 간격으로 자동으로 슬라이드 되는 기능은
setTimeout 함수를 통해 Next버튼이 클릭 되는 것을 구현하면 되는데, 함수 안에 재귀함수로 함수를 무한 실행 할 수 있도록 하고, 따로 함수를 최초 실행시킨다.

4) 재생/멈춤 버튼

// 재생/멈춤 버튼
let flag = true;
bnnPlayBtn.addEventListener('click', (e) => {
  if (flag) {
    bnnPlayBtn.classList.add('on');
    clearTimeout(autoBnn);
    flag = false; // flag = 0;
  } else {
    bnnPlayBtn.classList.remove('on');
    autoBnn = setTimeout(autoBanner, 3000);
    flag = true; // flag = 1;
  }
});

재생/멈춤 버튼은 불리언 값을 저장해 둘 flag 변수를 true로 생성하고 버튼에 클릭이 일어날 때 오토배너함수의 시간을 멈추고
flag 값을 바꾼다.물론 클래스도 변경해서 이미지를 바꿔준다.

5) 롤링 버튼

// 롤링 클릭
for (let i = 0; i < bnnRollA.length; i++) {
  bnnRollA[i].addEventListener('click', (e) => {
    e.preventDefault;
    clearTimeout(autoBnn);
    flag = false;
    bnnAction(i);
    bnnPlayBtn.classList.add('on');
    bnnNum = i;
  });
}

마지막으로 롤링 버튼을 클릭했을 때는 생각할 것이 많았다.

  • 오토배너(자동 슬라이드) 멈출 것
  • 재생/멈춤 버튼의 flag값을 클릭했을 때 처럼 false로 만들 것
  • 다시 재생 버튼을 눌렀을 때 해당 배너부터 오토배너가 실행되도록 할 것

오토배너를 멈추는 것은 clearTimeout함수로 해결하고,버튼이 클릭 되었을 때 flag 값을 false로 할당하는 것도 간단했다.

근데 다시 재생 버튼을 눌렀을때 해당 배너부터 오토배너가 실행되는 것에서 한참을 헤맸다.

잘 생각해 보면, 재생 버튼을 누르면 다시 오토배너 함수가 실행 될 것이고, 오토배너함수는 현재 카운트변수인 bnnNum를 증가 시키고 시작한다.

따라서 bnnNum을 클릭한 롤링 버튼의 인덱스 번호로 할당해서 문제를 해결했다.


# 자만감 No, 자신감 No

강의 중에 코드 작성해서 제출하라고 하면 어떻게든 구현해서 제출한다.

근데 20명중에 제출하는사람은 몇명 없다. 그렇다고 내가 코딩을 잘하냐? 절대 아니다.

얼마 전에 본 유튜브 영상에서 개발실력이 늘려면 자만감과 자신감을 버리라고 했다.

항상 배우는 자세에서 하나라도 더 배워야 좋은 개발자로 성장하는 올바른 길이라고.

지금 만들고 있는 이 웹에 사용된 기능들은 현업에서도 많이 사용된다고 한다. 물론 내가 직접 작성 할 줄 알아야 하고, 익숙해져야한다.

반복연습이 답이다.


# 오타 확인, 메소드의 정확한 기능 확인

오늘 contains()메소드 사용 중에 문자열을 누락해서 시간 낭비한 일이 있었다.

el.classList.contains('on') 라면 el의 class에 on이 있는지 확인해서 불리언 값을 반환하는 기능인데,,

맙소사 classList를 작성하지 않고 바로 el.contains() 이런 식으로 작성하고 오류를 찾지도 못하고 있던 것이다.

내가 사용하려는 메소드의 정확한 기능과 필요 요소들을 알고, 확인하고, 생각하고 작성하자.. 제발..!


오늘 끝, 내일 안녕

profile
https://kyledev.tistory.com/

0개의 댓글