質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.01%

ストップウォッチのカウント機能がうまく作動しない

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 99

hiroo_mokumoku

score 20

いつもお世話になってます。
javascript初学者です。
現在、簡易的なストップウォッチを作成してます。

ストップウォッチ機能

・startボタンをクリックしたら計測スタート
・stopボタンで一時停止、startボタンを押すと計測再開
・resetボタンを押した時に初期値(0.0)に戻る

今、困っていること

startボタンを押したらカウントが開始されます。
stopボタンを押したらカウントは止まります。
しかし、再度startボタンを押してカウントを再開させようとしたところ、何故か初期値(0.00)に戻ってカウントされてしまいます。

発生している問題・エラーメッセージ

特になし

該当のソースコード

<html>
  <head>
    <meta charset="utf-8" />
    <title>ストップウォッチ|1秒単位で計測</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        border: 0;
        font-size: 50px;
        font-display: sans-serif;
      }

      body {
        background-color: rgb(162, 237, 238);
        text-align: center;
        margin: 0 auto;
      }

      h1 {
        font-size: 40px;
        margin: 40px;
      }

      #timer {
        margin-bottom: 20px;
      }

      .myButton {
        font-size: 25px;
        margin: 5px;
        padding: 5px;
        border-radius: 5px;
      }
    </style>
  </head>

  <body>
    <h1>ストップウォッチ|1秒単位で計測</h1>
    <div id="timer">0.00</div>
    <input type="button" class="myButton" value="start" onClick="start();" />
    <input type="button" class="myButton" value="stop" onClick="stop();" />
    <input type="button" class="myButton" value="reset" onClick="reset();" />

    <script type="text/javascript" src="test.js"></script>
    <!--
    <script type="text/javascript" src="191103.js"></script>
    -->
  </body>
</html>
var startTime = 0;
var stopTime = 0;
var timerId;
var stopCalc = 0;

function start() {
  startTime = Date.now();
  CountTime();
}

function stop() {
  clearTimeout(timerId);
  stopCalc += Date.now() - startTime;
}

function reset() {
  var resetText = document.getElementById("timer");
  resetText.textContent = "0.00";
}

function CountTime() {
  timerId = setTimeout(function() {
    var CountTimeCalc = Date.now() - startTime + stopTime;
    var CountTimeText = document.getElementById("timer");
    CountTimeText.textContent = (CountTimeCalc / 1000).toFixed(2);
    CountTime();
  }, 100);
}

試したこと①

CountTime関数startボタンを押した時stopボタンを押した時の時間を計算処理してます。
stop関数の計算処理方法が間違っているのかそもそもこのロジックが間違っているのか自分では判断できないので困ってます。ご教示の程よろしくお願いします。

//CountTime関数
function CountTime() {
  timerId = setTimeout(function() {
    var CountTimeCalc = Date.now() - startTime + stopTime;
    var CountTimeText = document.getElementById("timer");
    CountTimeText.textContent = (CountTimeCalc / 1000).toFixed(2);
    CountTime();
  }, 100);
}

試したこと②

stop関数に下記のコードを追記するとstopボタンを押した後にstartボタンを押すとカウントが再開できるようになりました。
しかし、今度はstartボタンからresetボタンを押したら何故か初期値(0.0)に戻らなくなりました。
ご指摘頂いたstart関数についてもう少し検証していきたいと思います。

//stop関数
function stop() {
 //追加したコード
  stopTime += Date.now() - startTime;
  clearTimeout(timerId);
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+1

こんな感じでは?

<script>
window.addEventListener('DOMContentLoaded', ()=>{
  var startTime = 0;
  var stopTime = 0;
  var timerId;
  const timer = document.querySelector('#timer');
  const start=document.querySelector('#start');
  const stop =document.querySelector('#stop');
  const reset=document.querySelector('#reset');
  const setButtonDisabled=flg=>{
    start.disabled=flg;
    stop.disabled=!flg;
    reset.disabled=flg;
  };
  start.addEventListener('click',()=>{
    setButtonDisabled(true);
    startTime = Date.now()-stopTime;
    timerId = setInterval(()=>{
      stopTime = Date.now() - startTime;
      timer.textContent = (stopTime / 1000).toFixed(2);
    }, 100);
  });
  stop.addEventListener('click',()=>{
    clearTimeout(timerId);
    setButtonDisabled(false);
  });
  reset.addEventListener('click',()=>{
    timer.textContent = "0.00";
    stopTime = 0;
  });
});
</script>
<h1>ストップウォッチ|1秒単位で計測</h1>
<div id="timer">0.00</div>
<input type="button" id="start" value="start">
<input type="button" id="stop"  value="stop" disabled>
<input type="button" id="reset" value="reset">

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/11/09 23:53

    今回のベストアンサーとさせていただきます。
    回答ありがとうございました。

    キャンセル

0

再度startボタンを押してカウントを再開させようとしたところ、何故か初期値(0.00)に戻ってカウントされてしまいます。 

start関数内でstartTime = Date.now();しているからです。
継続したいのであれば、止まった時の秒数をどこかに持っておいて、それを足すようなロジックを組むとかする必要があります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/11/04 17:05 編集

    早速の回答ありがとうございます。
    >>止まった時の秒数をどこかに持っておいて
    つまり、止まった時の秒数用の「関数」もしくは「変数」を作成すれば良いという認識で合ってますか?

    キャンセル

  • 2019/11/04 17:36

    「stopCalc」は何のためにとっているのでしょう。(もし何かのコードを参考にされているのであれば、出典を明らかにされたほうがよいです)

    キャンセル

  • 2019/11/04 19:33 編集

    >>「stopCalc」は何のためにとっているのでしょう。
    すみません、再度コードを見直したところstopCalcの処理は不要だと判明しました。
    なので、削除してます。
    ちなみにstopCalcの処理を行っていた理由はスタートボタンを押した時に計測される時間とストップボタンを押した時に計測される時間を算出したかったのでstopCalcを使用してました。

    キャンセル

  • 2019/11/04 20:22

    出典もとのコードを確認してみてください、多分必要だから使用していると思いますよ。

    キャンセル

-1

start()を発火した際に、毎回

startTime = Date.now();


をしているのが原因だと思います。
start()を

if(startTime ==0){
startTime = Date.now()
}
CountTime();


とし、reset()を

startTime = 0
var resetText = document.getElementById("timer");
resetText.textContent = "0.00";


とすれば動くと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/11/04 17:11 編集

    回答ありがとうございます。
    頂いたコードを試させていただくと同時に
    自分でももう少しうまくカウントされない原因を追求していきたいと思います。

    キャンセル

  • 2019/11/04 17:33

    To: YukiSaegusaさん
    そう書くと、「計測再開」ではなく最初のスタート時からストップまでの秒数になりませんか?

    キャンセル

  • 2019/11/04 17:41

    すみません、その通りですね、、、

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.01%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる