JSFiddle - React, Tailwind, and code Playground

by cedric_tarou

HTML

<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>My Stopwatch</title>
  <link rel="stylesheet" href="style.css">
</head>
<div class="container">
  <div class="space-timer">
    <div id="timer">00:00.000</div>
  </div>
  <div class="space-controller">
    <div class="btn" id="start">start</div>
    <div class="btn" id="stop">stop</div>
    <div class="btn" id="reset">reset</div>
  </div>
</div>

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

</html>

CSS

body {
  margin: 0;
  padding: 0;
  background: #ffeeff;
}

.container {
  width: 450px;
  height: 300px;
  background: #eeffee;
  margin: 0 auto;
  text-align: center;
  margin-top: 50px;
  padding: 20px;
}

.container .space-timer {
  margin: 0 auto;
  width: 80%;
  height: 200px;
  line-height: 200px;
  background: white;
  font-size: 3rem;
  border: 1px solid black;
  margin-bottom: 20px;
}

.container .space-controller {
  margin: 0 auto;
  width: 80%;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-pack: justify;
      -ms-flex-pack: justify;
          justify-content: space-between;
}

.container .space-controller .btn {
  border: 1px solid black;
  width: 100px;
  height: 45px;
  line-height: 45px;
  background: white;
  font-weight: bold;
  cursor: pointer;
  -webkit-user-select: none;
     -moz-user-select: none;
      -ms-user-select: none;
          user-select: none;
}

.container .space-controller .inactive {
  opacity: 0.4;
}
/*# sourceMappingURL=style.css.map */

JavaScript

'use strict';
{
  const timer = document.getElementById('timer');
  const start = document.getElementById('start');
  const stop = document.getElementById('stop');
  const reset = document.getElementById('reset');
  let startTime;  
  let timeoutId;
  let elapsedTime = 0;

  const countUp = () => {
    // new Date()は時間を時間形式で表示するために必要
    const d = new Date(Date.now() - startTime + elapsedTime);
    const m = String(d.getMinutes()).padStart(2, '0');
    const s = String(d.getSeconds()).padStart(2, '0');
    const ms = String(d.getMilliseconds()).padStart(3, '0');
    timer.textContent = `${m}:${s}.${ms}`;
    timeoutId = setTimeout(() => {
      countUp();
      // return timeoutId;
    }, 10); 
  };

  const setButtonStateInitial  = () => {
    start.classList.remove('inactive');
    stop.classList.add('inactive');
    reset.classList.add('inactive');
  };
  const setButtonStateRunning  = () => {
    start.classList.add('inactive');
    stop.classList.remove('inactive');
    reset.classList.add('inactive');
  };
  const setButtonStateStopped  = () => {
    start.classList.remove('inactive');
    stop.classList.add('inactive');
    reset.classList.remove('inactive');
  };

  setButtonStateInitial();

  start.addEventListener('click', () => {
    if (start.classList.contains('inactive')=== true) {
      return;
    }
    setButtonStateRunning();
    startTime = Date.now();
    countUp();
  });
  stop.addEventListener('click', () => {
    if (stop.classList.contains('inactive')=== true) {
      return;
    }
    setButtonStateStopped();
    clearTimeout(timeoutId);
    elapsedTime += (Date.now() - startTime);
    // timer.textContent = 'Stop!';
  });
  reset.addEventListener('click', () => {
    if (reset.classList.contains('inactive')=== true) {
      return;
    }
    setButtonStateInitial();
    timer.textContent = '00:00.000';
    elapsedTime = 0;
  });
}