이전에 노마드코더의 클론코딩 강의에서 시도했다가 실패했던 것과 비슷한 챕터다… 타이머 기능이라고 하면 굉장히 쉬워보이지만…. 막상 해보면 굉장히 복잡하다.
로직
const와 addEventListener
초(seconds)입력하면 → 분 : 초 형식으로 화면에 띄우기
input 박스 입력된 값을 함수에 전달!
띄워진 시간 countdown
타이머 종료 시간(endTime) 계산 → 띄우기
const와 addEventListener 1 2 3 4 5 6 7 8 9 const time = document .querySelector('.display__time-left' );const endTime = document .querySelector('.display__end-time' );const buttons = document .querySelectorAll('[data-time]' );function startTimer ( ) { } buttons.forEach((button ) => button.addEventListener('click' , startTimer));
Seconds입력 → Minutes : Seconds 형식으로 반환
💡 분(Minutes) : 초 / 60초 (Seconds) : 초 % 60
1 2 3 4 5 function displayTimer (seconds ) { const minutes = Math .floor(seconds / 60 ); const secondsLeft = seconds % 60 ; time.innerHTML = `${minutes} :${secondsLeft} ` ; }
But, 이대로 실행할 경우 아래와 같은 문제가 발생한다
1 2 3 4 5 6 7 8 9 function displayTimer (seconds ) { const minutes = Math .floor(seconds / 60 ); const secondsLeft = seconds % 60 ; const display = `${minutes} :${secondsLeft < 10 ? '0' : '' } ${secondsLeft} ` ; document .title = display; time.innerHTML = display; }
지금 다시 코드를 봐보니까.. padend
나 padstart
를 사용했어도 됐을 것 같다.
💡 submit
이벤트에 반응할 엘리먼트 및 함수를 만들고, 해당 함수에서 timer에 분값*60을 전송
→ timer(seconds)
에서 displayTimer()
함수 실행하면 된다.
1 2 3 4 5 6 7 8 9 10 11 function timer (seconds ) { displayTimer(seconds); } function submitSeconds (e ) { e.preventDefault(); const inputMins = this .minutes.value; timer(inputMins * 60 ); } document .customForm.addEventListener('submit' , submitSeconds);
띄워진 시간을 카운트다운!
💡 가장 핵심적인 부분이다.
setInterval
을 활용해 1초마다 seconds가 —1 되도록 하고 → seconds가 00을 지나 마이너스 되면 → minutes가 —1 되도록 구현하면 된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 function timer (seconds ) { const now = Date .now(); const then = now + seconds * 1000 ; console .log(now, then); displayTimer(seconds); countdown = setInterval (() => { const countSeconds = Math .round((then - Date .now()) / 1000 ); if (countSeconds < 0 ) { clearInterval (countdown); return ; } displayTimer(countSeconds); }, 1000 ); }
부가설명
⇒ 즉, 고정된 시간 값 (then)에서 계속 증가하는 값을 빼주면 결국 countSeconds는 1초씩 줄어들게 된다.
종료시간 표시하기
💡 위의 내용들을 잘 수행했다면 어렵지 않다.
1 2 3 4 5 6 7 8 function displayEndTime (timestamp ) { const end = new Date (timestamp); const hours = end.getHours(); const minutes = end.getMinutes(); endTime.textContent = `종료 시간 ${ hours < 10 ? '0' : '' } ${hours} : ${minutes} ` ;}
최종 완성 코드 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 let countdown;let working = false ;const time = document .querySelector('.display__time-left' );const endTime = document .querySelector('.display__end-time' );const buttons = document .querySelectorAll('[data-time]' );const quit = document .querySelector('.quit' );function timer (seconds ) { working = true ; if (working == false ) { return ; } clearInterval (countdown); quit.style.setProperty('opacity' , '100' ); const now = Date .now(); const then = now + seconds * 1000 ; displayTimer(seconds); displayEndTime(then); countdown = setInterval (() => { const countSeconds = Math .round((then - Date .now()) / 1000 ); if (countSeconds < 0 ) { clearInterval (countdown); return ; } displayTimer(countSeconds); }, 1000 ); } function displayTimer (seconds ) { const minutes = Math .floor(seconds / 60 ); const secondsLeft = seconds % 60 ; const display = `${minutes} :${secondsLeft < 10 ? '0' : '' } ${secondsLeft} ` ; document .title = display; time.innerHTML = display; } function displayEndTime (timestamp ) { const end = new Date (timestamp); const hours = end.getHours(); const minutes = end.getMinutes(); endTime.textContent = `종료 시간 ${hours < 10 ? '0' : '' } ${hours} : ${ minutes < 10 ? '0' : '' } ${minutes} ` ;} function startTimer ( ) { const seconds = parseInt (this .dataset.time); timer(seconds); } function quitTimer ( ) { clearInterval (countdown); working = false ; } buttons.forEach((button ) => button.addEventListener('click' , startTimer)); quit.addEventListener('click' , quitTimer); document .customForm.addEventListener('submit' , submitSeconds);function submitSeconds (e ) { e.preventDefault(); const inputMins = this .minutes.value; timer(inputMins * 60 ); this .reset(); }