[PJT] vanillaJS로 Countdown timer 만들기

돗개·2020년 12월 30일
2

vanillaJS 프로젝트

목록 보기
1/2
post-thumbnail

mini PJT made with 'vanilla JS' only

해당 시리즈에는 vanillaJS로만 만든 미니 플젝을 올릴 계획이다.
처음에는 프레임워크 중심으로 공부를 했지만, vanillaJS를 잘 다뤄야 어떤 프레임워크도 잘 다룰 수 있다는 사실을 깨달았기 때문에! 이 시리즈를 기획하게 되었다.


Countdown timer

오늘 만들어볼 미니 프로젝트는 countdown timer 이다.
이벤트와 디데이를 작성해 현재 날짜로부터 남은 날짜와 시간을 알려주는 웹앱이다.


- setting


- countdown 구현

1) new Date()

countdown 기능을 구현하기 위해서는 오늘 날짜와 디데이 날짜가 필요하다. new Date() 함수를 활용해 오늘 날짜를 구하고, 괄호 안에 디데이 날짜를 넣어준다.
Wed Dec 30 2020 20:19:09 GMT+0900 (대한민국 표준시) 이런 식으로 결과가 나온다.

2) timestamp

위의 형식으로는 계산을 하기 어렵기 때문에, 위의 값을 ms단위로 변경해보자. (timestamp)
+ new Date() 처럼 앞에 + 만 붙여주면, 1609327542321 이렇게 생긴 timestamp 값이 나와서 시간 계산하기 쉽다! (사실 연산하면 알아서 timestamp가 됨)

const totalSeconds = (d_day - today) / 1000;

const seconds = Math.floor(totalSeconds) % 60;
const minutes = Math.floor(totalSeconds / 60) % 60;
const hours = Math.floor(totalSeconds / 3600) % 24;
const days = Math.floor(totalSeconds / 3600 / 24);

추가로,
디데이가 지났을 때 (totalSeconds < 0), alert 창을 띄워주었다.
또한 시간, 분, 초가 한 자리 수일 때 0을 붙여 자릿수를 채워주는 함수를 작성했다.

function formatTime(time) {
    return time < 10 ? (`0${time}`) : time;
}

3) setInterval()

초마다 카운트다운을 하기 때문에 지정한 시간 간격만큼 함수를 실행 시켜주는 setInterval 함수를 써야한다.

setInterval(() => countdown(디데이), 1000);


여기까지만 하면 완성이지만,
더 욕심을 내서 사용자가 직접 이벤트 내용과 디데이를 작성하고 이벤트 리셋까지 할 수 있도록 만들어보기로 했다!!


- localStorage

사용자가 한 번 작성한 이벤트와 디데이는 다음 번에 접속해도 브라우저에 저장되어 있어야 하므로, localStorage를 사용해야 한다. 또한, 아직 localStorage에 저장된 값이 없으면 사용자가 이벤트와 디데이를 직접 입력할 수 있도록 해야한다.

localStorage는 key, value 값으로 저장된다. (개발자 도구에서 Application 탭에 들어가보면 확인할 수 있다!)

localStorage.getItem(key);         // 저장된 값 조회
localStorage.setItem(key, value);  // 값 저장하기
localStorage.clear();              // 저장된 값 모두 삭제

이제부터 좀 까다로운데..
로직의 순서에 맞게 (기능별로 쪼개서..) 함수를 작성해야 한다.

먼저,
1) localStorage에 저장된 값을 조회해서, 값이 존재하지 않으면 이벤트와 디데이를 물어보는 함수를 불러온다.
1 - 1) 기본 값으로 폼의 인풋 창을 숨겨놓았기 때문에, classList.add()를 통해 인풋 창을 추가해준다. addEventListener("submit", 함수)를 써서, 제출하면 (1)이벤트 이름이 화면에 나오도록 하는 함수와 (2)countdown을 실행하는 함수를 실행시킨다.
1 - 2) 작성한 디데이 값(.value)으로 countdown을 실행하고, localStorage에 값을 저장해준다.

2) 값이 존재한다면, 기존의 countdown 화면을 보여준다.


- Reset button

리셋 버튼을 통해 기존의 이벤트를 리셋하고, 재설정할 수 있도록 했다.

1) 버튼 클릭 시, localStorage의 값 모두 삭제하는 함수 불러오기
button.addEventlistener("click", handleReset)

1 - 1) localStorage 값을 모두 삭제한 뒤, 이벤트 이름이 있었던 제목을 숨겨준다.

2) 위에 작성했던 기존 함수를 불러오면, localStorage에 저장된 값이 없어졌으니 (로직에 따라) 자동으로 인풋창이 보여진다.

1) clearInterval()

이벤트를 리셋하면, 기존에 돌아가고 있던 countdown도 정지시키고, 안의 숫자들을 모두 0으로 만들어줘야 한다.

// clearInterval 사용법
const timer = setInterval(() => {    // setInterval 함수를 변수에 담아 사용
    countdown(date), 1000;
});

clearInterval(timer);

- Issues

1) classList.add / remove

상황에 맞게 요소를 보여주고, 숨기는 작업이 헷갈렸고, 실수를 했다.
css 파일에 showing 이라는 class명을 작성해서 디자인하고,
js 파일에서 SHOWING_ON = "showing" 이렇게 불러와서,
요소가 보여져야 할 때는 요소명.classList.add(SHOWING_ON), 안보여야 할 때는 요소명.classList.remove(SHOWING_ON) 이렇게 활용했다.

2) clearInterval()

처음에 clearInterval()이 작동하지 않았는데, setInterval 함수 내에서 제대로 사용하지 않았기 때문이다. 내부에서 작동을 멈추려면 flag가 필요했기 때문에 변수로 timeOn = false를 디폴트 값으로 두고, timeOn이 true면 timer가 작동, false면 멈추도록 작성했다.

function paintCountdown(date) {
  timeOn = true;
  const timer = setInterval(() => {
    if (timeOn) {
      countdown(date), 1000;
    } else {
      clearInterval(timer);
    }
  });
}

느낀점..

그 동안 튜토리얼을 보고 무언가를 만들어왔는데,
이번엔 내 힘으로 코드를 짜고, 기능들을 덧붙여 완성한 작품이라는 생각에 뿌듯했다. (물론 countdown 구현과 localStorage 관련해서 여러 문서를 참고했지만)

  • console 활용하기
    : 오류 메시지를 잘 읽어보지 않아 빠르게 해결할 수 있는 문제를 디버깅하는 데 오래 걸렸다. console 창을 잘 활용하고, 오류 메시지를 읽고, 그에 따라 어떻게 구글링할지 고민해봐야겠다.

  • 효율적인 구글링
    : 한 가지 문서를 잡고 있지말고, 여러 후보군을 정해 원하는 정보만 뽑아 쓰자. (새 탭 여러 개 띄워놓기)

  • 다양한 try 해보기
    : 뭔가 되지 않으면 생각만 하는 경향이 있었는데, 다양한 시도를 통해 경험치를 늘려가자.

더불어 css도 자연스레 늘게되어 구글링 횟수가 줄었다..!
이제 클래스 네이밍과 함수 로직 짜는 것에 좀 더 익숙해져야겠다.

profile
울보 개발자(멍.. 하고 울어요)

0개의 댓글