[JS] Day 29 - Countdown Timer

demo:

demo사이트

github:

Danji-ya


[JS] Day 29 - Countdown Timer

🎯 기능 요구사항

  • 카운트다운을 구현한다.
  • 검색 폼에 값을 입력 후 엔터를 치면 새롭게 카운트다운을 시작한다.
  • 각 버튼을 클릭 시 새롭게 카운트 다운을 시작한다.
  • 카운트다운 아래에 종료 시간을 보여준다.

🚀 배운 점

new Date()

Date 객체는 1970년 1월 1일 UTC(협정 세계시) 자정과의 시간 차이를 밀리초로 나타내는 정수 값을 반환해주기 때문에 입력 또는 설정된 초 단위에 1000을 곱하여 밀리 단위로 바꿔주어야 한다.

그리고 이를 이용하여 (설정된 시간 - 현재 시간) / 1000의 방식으로 카운트다운을 구현하면 된다.

function countdown(seconds) {
        if(timer) clearInterval(timer); // for restart

        const startTime = new Date().getTime();
        const endTime = startTime + seconds * 1000; //getTime() = ms

        displayRemainingTime(seconds);
        displayEndTime(endTime);

        timer = setInterval(() => {
            const remainingTime = Math.round((endTime - new Date().getTime()) / 1000);
            if(remainingTime < 0) return clearInterval(timer);

            displayRemainingTime(remainingTime);
        }, 1000);
}

HTMLFormElement.reset()

검색 폼에 값을 입력 후 엔터를 치고 새롭게 카운트다운을 시작할 때, 검색 폼을 초기값으로 돌리고 싶어 this.value(), this.textContent 방법을 써봤지만 원하는 방식대로 구현되지 않았다.

이를 해결하기 위해서는 this.reset() 메서드를 사용하면 된다.

function updateTimer(e) {
  e.preventDefault();

  countdown(this.minutes.value * 60);
  this.reset();
}

💻 최종코드

(function(){
    const $displayTimeLeft = document.querySelector(".display__time-left");
    const $displayEndTime = document.querySelector(".display__end-time");
    const $timerControls = document.querySelector(".timer__controls");
    const $sendForm = document.querySelector("#custom");

    let timer;

    function countdown(seconds) {
        if(timer) clearInterval(timer); // for restart

        const startTime = new Date().getTime();
        const endTime = startTime + seconds * 1000; //getTime() = ms

        displayRemainingTime(seconds);
        displayEndTime(endTime);

        timer = setInterval(() => {
            const remainingTime = Math.round((endTime - new Date().getTime()) / 1000);
            if(remainingTime < 0) return clearInterval(timer);

            displayRemainingTime(remainingTime);
        }, 1000);
    }

    function displayRemainingTime(sec) {
        const mins = Math.floor(sec / 60);
        const seconds = sec % 60;

        $displayTimeLeft.textContent = `${('00' + mins).slice(-2)}:${('00' + seconds).slice(-2)}`;
    }

    function displayEndTime(endTime) {
        const time = new Date(endTime);

        $displayEndTime.textContent = `${('00' + time.getHours()).slice(-2)}:${('00' + time.getMinutes()).slice(-2)}`;
    }

    function clickAction(e) {
        if(e.target.classList.contains("timer__button")){
            countdown(e.target.dataset.time);
        }
    }

    function updateTimer(e) {
        e.preventDefault();

        countdown(this.minutes.value * 60);
        this.reset();
    }

    $timerControls.addEventListener("click", clickAction);
    $sendForm.addEventListener("submit", updateTimer);
})();

좋은 웹페이지 즐겨찾기