자바스크립트 예제

스톱워치 + 타이머 예제 (setInterval & clearInterval)

자무카 2022. 12. 31.

유튜브 유노코딩 예제 : https://www.youtube.com/@user-mr8co8gy4p/featured

상당히 쉽게 설명하고, 예제가 좋다.

약간의 응용으로 타이머 추가.

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <link rel="stylesheet" href="./style.css" />
    <!-- <script defer src="./timer.js" type="text/javascript"></script> -->
  </head>

  <body>
    <div class="container">
   
      <h1>
        <span id="min">00</span> : <span id="sec">00</span> :
        <span id="tmsec">00</span>
      </h1>
      <h3>
        <button id="btn_start">스톱워치(시작)</button>
        <button id="btn_stop">정지</button>
        <button id="btn_reset">리셋</button>
      </h3>
      <h3>
        <button id="btn_3">3min</button>
        <button id="btn_5">5min</button>
        <button id="btn_10">10min</button>
      </h3>
    </div>

    <script src="./main.js"></script>
  </body>
</html>

 

@font-face {
    font-family: 'LABDigital';
    font-weight: normal;
    font-style: normal;
    src: url('https://cdn.jsdelivr.net/gh/webfontworld/fontlab/LABDigital.eot');
    src: url('https://cdn.jsdelivr.net/gh/webfontworld/fontlab/LABDigital.eot?#iefix') format('embedded-opentype'),
        url('https://cdn.jsdelivr.net/gh/webfontworld/fontlab/LABDigital.woff2') format('woff2'),
        url('https://cdn.jsdelivr.net/gh/webfontworld/fontlab/LABDigital.woff') format('woff'),
        url('https://cdn.jsdelivr.net/gh/webfontworld/fontlab/LABDigital.ttf') format("truetype");
    font-display: swap;
}

* { font-family: LABDigital;}

.container{
    width: 80%; min-width: 320px; max-width: 640px;
    margin: 10px auto; padding: 5px 0 15px;;
    text-align: center; border: 5px solid grey;
    border-radius: 16px;
    background-color: black;
}
h1{ color: red;}
/* 인라인블록+넓이 지정 안하면, 블록 넓이 변해서 떨림*/
h1 > span{
  display: inline-block;
  width: 40px;
}

button{
  color: darkslategray; background-color: lightgray;
  font-size: 16px; padding: 6px;
  width: 100px; border: none; border-radius: 3px;
  cursor: pointer;
}
button:active{
  color: lightgray;
  background-color: darkslategray;
}
let min = 0;
let sec = 0;
let tmsec = 0;
const minSpan = document.getElementById("min");
const secSpan = document.getElementById("sec");
const tmsecSpan = document.getElementById("tmsec");
const btnStart = document.getElementById("btn_start");
const btnStop = document.getElementById("btn_stop");
const btnReset = document.getElementById("btn_reset");
const btn_10 = document.getElementById("btn_10");
//시작 버튼 누르면, 셋인터벌->0.01초마다 증가 함수 호출
//onClick()대비, addEventListener 특징 3
// 1. 이벤트에 하나 이상의 핸들러를 등록할 수 있다.
// 2. HTML 요소 뿐만 아니라 모든 DOM 요소에 대해 동작한다.
// 3. 캡쳐링/버블링과 같은 이벤트 리스너에 대한 옵션을 지정하여 더욱 세밀한 제어가 가능하다.
//clickEvent.addEventListener('click', 이벤트 리스너, 버블링/캡쳐링)

// setIntervalId 는 0이 아닌 정수를 반환한다.
let intervalId;
btn_3.addEventListener('click', ()=> {
    clearInterval(intervalId);
    minSpan.textContent = "3";
    min = 3; sec = 0; tmsec = 0;
    intervalId = setInterval(countDown, 10);
    // countDown();
})
btn_5.addEventListener('click', ()=> {
    clearInterval(intervalId);
    minSpan.textContent = "5";
    min = 5; sec = 0; tmsec = 0;
    intervalId = setInterval(countDown, 10);
    // countDown();
})
btn_10.addEventListener('click', ()=> {
    clearInterval(intervalId);
    minSpan.textContent = "10";
    min = 10; sec = 0; tmsec = 0;
    intervalId = setInterval(countDown, 10);
    // countDown();
})
// btnStart.onclick = () => setInterval(countUp, 10);
btnStart.addEventListener('click', () => {
    clearInterval(intervalId); // intervalId 최신화
    intervalId = setInterval(countUp, 10);
    console.log("인터벌Id :", intervalId);
})
//setInterval 동작을 멈추기 위해서(clearInterval), 인터벌Id가 필요!
btnStop.addEventListener('click', ()=>{
    clearInterval(intervalId);
    console.log("인터벌Id :", intervalId);
})
btnReset.addEventListener('click', ()=>{
    clearInterval(intervalId);    
       tmsec = 0;
       sec = 0;
       min = 0;
       tmsecSpan.textContent = "00"
       secSpan.textContent = "00"
       minSpan.textContent = "00"
})

function countUp() {
    tmsec++;
    // console.log(tmsec);
    tmsecSpan.textContent = tmsec > 9 ? tmsec : '0' + tmsec;
    if(tmsec > 99){
        sec++;
        secSpan.textContent = sec > 9 ? sec :'0' + sec;
        tmsec = 0;
        tmsecSpan.textContent = "00"
    }
    if(sec > 59){
        min++;
        minSpan.textContent = min > 9 ? min : "0" + min;
        sec = 0;
        secSpan.textContent = "00"
    }
}
function countDown() {
    tmsec--;
    // console.log(tmsec);
    tmsecSpan.textContent = tmsec > 9 ? tmsec : '0' + tmsec;
    if(tmsec < 0){
        sec--;
        secSpan.textContent = sec > 9 ? sec :'0' + sec;
        tmsec = 99;
        tmsecSpan.textContent = "99"
    }
    if(sec < 0){
        min--;
        minSpan.textContent = min > 9 ? min : "0" + min;
        sec = 59;
        secSpan.textContent = "59"
    }
}

댓글