VanillaJS로 스톱워치 만들기

이번에는 Vanilla JS를 이용해 스톱워치를 만들어보자.

스톱워치 모듈

상태 이름 설명
_interval start() 시 실행되는 setInterval이 리턴하는 intervalID
_centisecond 현재 스톱워치의 시간 (단위: centisecond)
_lapCount 현재 스톱워치의 누적 Lap 갯수
_prevLap 직전 Lap 시간
메소드 이름 기능 리턴값
centisecond 현재 centisecond 값 가져오기 _centisecond
start 스톱워치 시작하기 null
pause 스톱워치 중단(일시정지)하기 null
createLap 스톱워치 Lap 생성하기 [_lapCount, 현재 Lap 시간]
reset 스톱워치 리셋하기 null

시작, 중단 기능 만들기

const setTime = (time) => {
    timer.innerText = time;
};

const handleStartStop = () => {
    if (isRunning === false) {
        isRunning = true;
        stopWatch.start();
        setInterval(() => {
            setTime(convertCentiSecondtoMinSecond(stopWatch.centisecond));
        }, 10);
        startStopBtnLabel.innerText = '중단';
        lapResetBtnLabel.innerText = '';
    } else {
        isRunning = false;
        stopWatch.pause();
        setTime(stopWatch.centisecond);
        startStopBtnLabel.innerText = '시작';
        lapResetBtnLabel.innerText = '리셋';
    }
    startStopBtn.classList.toggle('bg-green-600');
    startStopBtn.classList.toggle('bg-red-600');

랩/리셋 기능 구현하기

const handleLapReset = () => {
    if (isRunning === true) {
        appendLap();
    } else {
        stopWatch.reset();
        setTime(convertCentiSecondtoMinSecond(0));
        clearLaps();
    }
};

const appendLap = () => {
    const [lapCnt, lapTime] = stopWatch.createLap();
    const lap = document.createElement('li');
    lap.setAttribute('data-time', lapTime);
    lap.className = 'flex justify-between py-2 px-3 border-b-2';
    lap.innerHTML = `  
                        <span>랩 ${lapCnt}</span>
                        <span>${convertCentiSecondtoMinSecond(lapTime)}</span>
                    `;
    laps.prepend(lap);

}

키보드 조작 기능 구현

document.documentElement.addEventListener('keydown', (e) => handleKeyDown(e));

const handleKeyDown = (e) => {
    console.log(e.code);
    switch (e.code) {
        case 'KeyL':
            handleLapReset();
            break;
        case 'KeyS':
            handleStartStop();
            break;
        default:
            return;
    }
};

최단, 최장 기록 강조 기능 구현

const appendLap = () => {
    ...

    // first
    if (maxLap === undefined) {
        maxLap = lap;
        return;
    }
    // second
    if (minLap === undefined) {
        const maxTime = parseInt(maxLap.getAttribute('data-time'));
        if (lapTime > maxTime) {
            minLap = maxLap;
            maxLap = lap;
        } else {
            minLap = lap;
        }
        maxLap.classList.add('text-red-600');
        minLap.classList.add('text-green-600');
        return;
    }
    const maxTime = parseInt(maxLap.getAttribute('data-time'));
    const minTime = parseInt(minLap.getAttribute('data-time'));
    if (lapTime < minTime) {
        minLap.classList.remove('text-green-600');
        minLap = lap;
    } else if (lapTime > maxTime) {
        maxLap.classList.remove('text-red-600');
        maxLap = lap;
    }
    maxLap.classList.add('text-red-600');
    minLap.classList.add('text-green-600');
};

완성본

완성본 보러가기

끝!