이야기 정리

2. Stop watch와 Timer - 스톱워치 만들기 본문

Project/JavaScript project

2. Stop watch와 Timer - 스톱워치 만들기

jinhistory 2023. 1. 18. 16:06

목차

2. Stop watch와 Timer - 스톱워치 만들기
2-2. Stop watch와 Timer - 타이머 만들기

 

현대인에게 한시도 떼어놓을 수 없는 물건은 무엇일까? 당연히 핸드폰이다.

핸드폰 배터리가 10% 이하로 내려가면 점점 초조해지는건 많은 사람들이 공감할 것이다.

사람들에게 중요한 핸드폰에 꼭 들어가는 초기 어플들이 몇가지 있다. 캘린더, 사진, 메모, 카메라, 그리고 시계다.

어떤 핸드폰도 시계에 알람과 스톱워치, 타이머 기능이 탑재되어 있다. 그만큼 시간은 사람들에게 중요한 요소이다. 때문에 두번째 프로젝트로는 스톱워치와 타이머를 선택했다.

두개의 기능을 동시에 만드는 만큼 각각 필요한 요소들을 적어보았다.

 

어떤 기능이 필요할까? : 스톱워치
  • 현재 초를 표기하는 화면
  • 시작 버튼
  • 리셋 버튼
  • 중간에 시간을 저장할 수 있는 랩 버튼
  • 랩을 하단 리스트로 보기
어떤 기능이 필요할까? : 타이머
  • 시간을 선택할 수 있는 기능 (최대 10분)
  • 일시정지 버튼
  • 리셋버튼
  • 타이머 종료까지 남은 시간 표시
  • 타이머가 종료되면 안내창 띄우기

 

다음은 완성된 최종 코드다.

See the Pen Untitled by beren-105 (@beren-105) on CodePen.

 

스톱워치 만들기


//스톱워치 이벤트
let mins = 0
let seconds = 0
let milliseconds = 0

let time = 0
let index = 0
let interval

const startBtn = document.querySelector('.stop-watch-start')
const resetBtn = document.querySelector('#stop-watch-reset')
const rapBtn = document.querySelector('.stop-watch-rap')
const h1 = document.querySelector('.stop-watch-time')


// start 버튼 이벤트
let click = true

startBtn.addEventListener('click', ()=> {
    startBtn.innerText = 'START'
    
    if (click) {
        startBtn.classList.add('stop')
        startBtn.innerText = 'STOP'
        interval = setInterval(startWatch, 10);
        click = false
    } else if (!click) {
        clearInterval(interval)
        startBtn.innerText = 'START'
        startBtn.classList.remove('stop')
        startBtn.classList.add('active')
        click = true
    }
})

// 시간 계산
function startWatch() {
    milliseconds++
    
    if (milliseconds >= 100) {
        milliseconds = 0
        seconds++
    }
    if (seconds >= 60) {
        seconds = 0
        mins++
    }

    h1.innerHTML = `
    <span>${mins < 10 ? "0" + mins : mins}</span>:<span>${seconds < 10 ? "0" + seconds : seconds}</span>:<span class="milliseconds">${milliseconds < 10 ? "0" + milliseconds : milliseconds}</span>
    `
}
  • 첫 시작은 시간 계산과 스타트 버튼 클릭 이벤트다.
  • 스톱워치는 정확한 시간을 재기 위한 것이므로 0.01초 단위까지 확인 가능하도록 만들었다.
  • 스타트 버튼을 클릭할 시, 스톱 버튼으로 바뀐다. 그리고 스톱 버튼을 클릭할 시, 다시 스타트 버튼으로 변경된다.

 

발생한 문제점
  • 버튼을 클릭해도 스타트 버튼의 innerText가 작동하지 않아 STOP 글자를 띄울 수 없었다.
  • 원인을 몰라 임시 방편으로 button안에 span 태그를 추가하고, firstElementChild로 span의 내용을 변경했다. 그러나 이 방법은 코드가 길어보이고, 필요없는 span 태그가 추가됐다.
해결방법
  • 원인은 버튼 내의 글씨는 처음부터 innerText로 만들어지지 않았기 때문에 변경되지 않는 것이었다.
  • span 태그를 지우고, 대신 클릭 이벤트가 시작하자마자 innerText = 'START'를 추가했다.

 

 

다음으로는 클릭 시 클릭한 시간을 저장할 수 있는 랩 버튼과 리셋 버튼이다.

// reset 버튼 이벤트
resetBtn.addEventListener('click', ()=> {
    clearInterval(interval)
    mins = 0
    seconds = 0
    milliseconds = 0
    
    h1.innerHTML = `
    <span>00</span>:<span>00</span>:<span class="milliseconds">00</span>
    `

    if (click) {
        startBtn.classList.remove('active')
    } else if (!click) {
        startBtn.innerText = 'START'
        startBtn.classList.remove('stop')
    }
    click = true

    const li = document.querySelectorAll('.rap-list')
    li.forEach((lis)=> {
        lis.remove()
    })
})


// rap 버튼 이벤트
rapBtn.addEventListener('click', (e)=> {

    if (index < 5) {
        index++

        // rap 생성
        const ul = document.querySelector('.rap-lists')
        const li = document.createElement('li')
        li.classList.add('rap-list')
        li.innerHTML = `
            <span>${(mins < 10 ? "0" + mins : mins) + ':' + (seconds < 10 ? "0" + seconds : seconds) + ':' + (milliseconds < 10 ? "0" + milliseconds : milliseconds)}</span>
            <svg class="close-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M310.6 150.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L160 210.7 54.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L114.7 256 9.4 361.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L160 301.3 265.4 406.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L205.3 256 310.6 150.6z"/></svg>
        `
        ul.prepend(li)

        // rap 제거
        const closeBtn = document.querySelector('.close-icon')
        closeBtn.addEventListener('click', (e)=> {
            index--
            if (e.currentTarget === closeBtn) {
                e.currentTarget.parentNode.remove()
            }
        })
    } else {
        e.preventDefault()
    }
})
  • 이전 to do list에서는 리스트를 생성하는데 갯수 제한이 없었다. 이번에는 사용자가 만들 수 있는 리스트 숫자를 제한하는 기능을 추가했다.
  • 또한 리셋 버튼을 누를 시 리스트를 한꺼번에 지울 수 있는 기능 역시 추가했다.

 

다음 글에서는 화면을 타이머로 전환하는 탭 버튼과, 타이머 기능을 구현할 예정이다.

Comments