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

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

ただいまの
回答率

87.37%

計算結果を時間表したい

解決済

回答 2

投稿

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

score 9

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>Stopwatch</title>
  <link rel="stylesheet" href="styles.css">

</head>
<body>
  <div id="timer">00:00.000</div>
  <button id="start">Start</button>
  <button id="stop">Stop</button>
  <button id="reset">Reset</button>
    <select name="mintus" id ="mintus" class="mintus">
      <option value="time_1" id="time1">30</option>
      <option value="time_2" id="time2">60</option>
      <option value="time_3" id="time3">90</option>
    </select>
  <div>
    <button id="sum">計算</button>
    <div id="sum_account" ></div>
  </div>


  <script src="main.js"></script>
</body>
</html>
'use strict';

{
  const timer = document.getElementById('timer');
  const start = document.getElementById('start');
  const stop = document.getElementById('stop');
  const reset = document.getElementById('reset');
  const mintus = document.getElementById('mintus');
  const math = document.getElementById('sum');
  const sum_account = document.getElementById('sum_account');

  let startTime;
  let timeoutId;
  let elapsedTime = 0;


  function countUp() {
    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();
    }, 10);
  }

  function setButtonStateInitial() {
    start.disabled = false;
    stop.disabled = true;
    reset.disabled = true;
  }

  function setButtonStateRunning() {
    start.disabled = true;
    stop.disabled = false;
    reset.disabled = true;
  }

  function setButtonStateStopped() {
    start.disabled = false;
    stop.disabled = true;
    reset.disabled = false;
  }

  // 残り時間の計算
  function calculateRemaining(timeTxt) {
    const timeresult = mintus.value;
    switch(timeresult) {
      case 'time_1':
         const result1 = 3000000 - timeTxt;

         sum_account.innerHTML = result1;
         break;
      case 'time_2':
        const result2 = 6000000 - timeTxt;
        sum_account.innerHTML = result2;
        break;
      case 'time_3':
        const result3 = 9000000 - timeTxt;
        sum_account.innerHTML = result3;
        break;
      }
  }



  setButtonStateInitial();

  start.addEventListener('click', () => {
    setButtonStateRunning();
    startTime = Date.now();
    countUp();
  });

  stop.addEventListener('click', () => {
    setButtonStateStopped();
    clearTimeout(timeoutId);
    elapsedTime += Date.now() - startTime;
  });

  reset.addEventListener('click', () => {
    setButtonStateInitial();
    timer.textContent = '00:00.000';
    elapsedTime = 0;
  });


  math.addEventListener('click', () => {
    let timeTxt = timer.textContent.replace(":", "").replace(".", "");
    stop.click();
    calculateRemaining(timeTxt);
  });
}

計算結果の表示を〇〇分〇〇秒、〇〇という表示にしたいです。
何か知見をお教えくださいと

  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

0

表示されている数値から計算しました。

'use strict';

{
    const timer = document.getElementById('timer');
    const start = document.getElementById('start');
    const stop = document.getElementById('stop');
    const reset = document.getElementById('reset');
    const mintus = document.getElementById('mintus');
    const math = document.getElementById('sum');
    const sum_account = document.getElementById('sum_account');

    let startTime;
    let timeoutId;
    let elapsedTime = 0;


    function countUp() {
        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();
        }, 10);
    }

    function setButtonStateInitial() {
        start.disabled = false;
        stop.disabled = true;
        reset.disabled = true;
    }

    function setButtonStateRunning() {
        start.disabled = true;
        stop.disabled = false;
        reset.disabled = true;
    }

    function setButtonStateStopped() {
        start.disabled = false;
        stop.disabled = true;
        reset.disabled = false;
    }

    // 残り時間の計算
    function calculateRemaining(timeTxt) {
        const match = timeTxt.match(/^(\d+):(\d+\.\d+)$/);
        if (match == null) return;
        const time = match[1] * 60 + match[2];
        const result = mintus.children[mintus.selectedIndex].innerText * 60 - time;
        sum_account.innerHTML = `${Math.floor(result / 60)}:${Math.round(result % 60 * 1000) / 1000}`;

        // const timeresult = mintus.value;
        // switch (timeresult) {
        //     case 'time_1':
        //         const result1 = 3000000 - timeTxt;

        //         sum_account.innerHTML = result1;
        //         break;
        //     case 'time_2':
        //         const result2 = 6000000 - timeTxt;
        //         sum_account.innerHTML = result2;
        //         break;
        //     case 'time_3':
        //         const result3 = 9000000 - timeTxt;
        //         sum_account.innerHTML = result3;
        //         break;
        // }
    }



    setButtonStateInitial();

    start.addEventListener('click', () => {
        setButtonStateRunning();
        startTime = Date.now();
        countUp();
    });

    stop.addEventListener('click', () => {
        setButtonStateStopped();
        clearTimeout(timeoutId);
        elapsedTime += Date.now() - startTime;
    });

    reset.addEventListener('click', () => {
        setButtonStateInitial();
        timer.textContent = '00:00.000';
        elapsedTime = 0;
    });


    math.addEventListener('click', () => {
        // let timeTxt = timer.textContent.replace(":", "").replace(".", "");
        stop.click();
        // calculateRemaining(timeTxt);
        calculateRemaining(timer.textContent);
    });
}

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/09/26 22:44

    ありがとうございます。
    理解できてない部分があるのでconst time = match[1] * 60 + match[2];
    const result = mintus.children[mintus.selectedIndex].innerText * 60 - time;
    sum_account.innerHTML = `${Math.floor(result / 60)}:${Math.round(result % 60 * 1000) / 1000}`;
    を少し説明していただけないでしょうか?

    キャンセル

  • 2020/09/26 23:06

    > const match = timeTxt.match(/^(\d+):(\d+\.\d+)$/);
    match[1] に分が、match[2] に秒以降がはいります。

    > const time = match[1] * 60 + match[2];
    分を 60 倍して秒と加算することにより、全体を秒に直しています。

    > const result = mintus.children[mintus.selectedIndex].innerText * 60 - time;
    mintus.selectedIndex は mintus の選択されたインデクスです。
    30 なら 0 が、60 なら 1 が、90 なら 2 になります。
    mintus.children[mintus.selectedIndex] は 30 60 90 のいずれか選択された要素になります。
    mintus.children[mintus.selectedIndex].innerText は 30 60 90 のいずれか選択された値になります。
    それに 60 をかけることにより秒に直し、経過時間を引くことで残り時間を求めています。

    > sum_account.innerHTML = `${Math.floor(result / 60)}:${Math.round(result % 60 * 1000) / 1000}`;
    テンプレートリテラルで Math.floor(result / 60) と Math.round(result % 60 * 1000) / 1000 を文字列中に埋め込んでいます。
    https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Template_literals
    Math.floor(result / 60) は残り時間を 60 で割って小数点以下を切り捨てたもので、分を表します。
    Math.round(result % 60 * 1000) / 1000 は残り時間を 60 で割った余りを 1000 倍し、小数点以下を切り捨てて 1000 で割ることにより、秒を小数点以下三桁まで求めています。
    これらをコロンを挟んだ両側に置くことで「分:秒」の形にしています。

    キャンセル

  • 2020/09/26 23:16

    ありがとうございます。
    勉強します

    キャンセル

0

dをグローバルに持たせるなど工夫が必要では?

<script>

'use strict';
var d=new Date(0);
window.addEventListener('DOMContentLoaded', ()=>{
  const timer = document.getElementById('timer');
  const start = document.getElementById('start');
  const stop = document.getElementById('stop');
  const reset = document.getElementById('reset');
  const mintus = document.getElementById('mintus');
  const math = document.getElementById('sum');
  const sum_account = document.getElementById('sum_account');

  let startTime;
  let timeoutId;
  let elapsedTime = 0;

  function format_time(d){
    const m = String(d.getMinutes()+(d.getHours()-9)*60).padStart(2, '0');
    const s = String(d.getSeconds()).padStart(2, '0');
    const ms = String(d.getMilliseconds()).padStart(3, '0');
    return `${m}:${s}.${ms}`;
  }

  function countUp() {
    d = new Date(Date.now() - startTime + elapsedTime);
    timer.textContent = format_time(d);

    timeoutId = setTimeout(() => {
      countUp();
    }, 10);
  }

  function setButtonStateInitial() {
    start.disabled = false;
    stop.disabled = true;
    reset.disabled = true;
  }

  function setButtonStateRunning() {
    start.disabled = true;
    stop.disabled = false;
    reset.disabled = true;
  }

  function setButtonStateStopped() {
    start.disabled = false;
    stop.disabled = true;
    reset.disabled = false;
  }

  function calculateRemaining(timeTxt) {
    const m = parseInt(mintus.options[mintus.selectedIndex].textContent);
    const result1 = new Date(d.getTime());
    result1.setMinutes(m-result1.getMinutes());
    result1.setSeconds(-result1.getSeconds());
    result1.setMilliseconds(-result1.getMilliseconds());
    sum_account.innerHTML = format_time(result1);
  }



  setButtonStateInitial();

  start.addEventListener('click', () => {
    setButtonStateRunning();
    startTime = Date.now();
    countUp();
  });

  stop.addEventListener('click', () => {
    setButtonStateStopped();
    clearTimeout(timeoutId);
    elapsedTime += Date.now() - startTime;
  });

  reset.addEventListener('click', () => {
    setButtonStateInitial();
    timer.textContent = '00:00.000';
    elapsedTime = 0;
  });


  math.addEventListener('click', () => {
    let timeTxt = timer.textContent.replace(":", "").replace(".", "");
    stop.click();
    calculateRemaining(timeTxt);
  });
});
</script>

<div id="timer">00:00.000</div>
  <button id="start">Start</button>
  <button id="stop">Stop</button>
  <button id="reset">Reset</button>
    <select name="mintus" id ="mintus" class="mintus">
      <option value="time_1" id="time1">30</option>
      <option value="time_2" id="time2">60</option>
      <option value="time_3" id="time3">90</option>
    </select>
  <div>
    <button id="sum">計算</button>
    <div id="sum_account" ></div>
  </div>

調整版

<script>
'use strict';
var current_d=0;
var prev_d=0;
window.addEventListener('DOMContentLoaded', ()=>{
  const timer = document.querySelector('#timer');
  const start = document.querySelector('#start');
  const stop = document.querySelector('#stop');
  const reset = document.querySelector('#reset');
  const mintus = document.querySelector('#mintus');
  const math = document.querySelector('#sum');
  const sum_account = document.querySelector('#sum_account');
  let timerId;

  stop.disabled=true;

  const format_time=(d)=>{
    const m = parseInt(d/60/1000).toString().padStart(2, '0');
    const s = (parseInt(d/1000)%60).toString().padStart(2, '0');
    const ms = (d%1000).toString().padStart(3, '0');
    return `${m}:${s}.${ms}`;
  };
  start.addEventListener('click',()=>{
    var now=new Date();
    start.disabled=true;
    stop.disabled=false;
    reset.disabled=true;
    timerId=setInterval(()=>{
      current_d=new Date().getTime()-now.getTime()+prev_d;
      timer.textContent=format_time(current_d);
    },10);
  });
  stop.addEventListener('click',()=>{
    start.disabled=false;
    stop.disabled=true;
    reset.disabled=false;
    clearInterval(timerId);
    prev_d=current_d;
  });
  reset.addEventListener('click',()=>{
    current_d=0;
    prev_d=0;
    timer.textContent=format_time(current_d);
  });
  math.addEventListener('click',()=>{
    const m=parseInt(mintus.options[mintus.selectedIndex].textContent);
    sum_account.textContent=format_time(m*60*1000-current_d);
  });
});
</script>
<div id="timer">00:00.000</div>
  <button id="start">Start</button>
  <button id="stop">Stop</button>
  <button id="reset">Reset</button>
    <select name="mintus" id ="mintus">
      <option value="time_1">30</option>
      <option value="time_2">60</option>
      <option value="time_3">90</option>
    </select>
  <div>
    <button id="sum">計算</button>
    <div id="sum_account" ></div>
  </div>

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/09/26 18:27

    グローバルに持たせるとはどういうことでしょう?

    キャンセル

  • 2020/09/26 18:30 編集

    スコープ外でvar宣言することです

    「var d」の部分です

    キャンセル

  • 2020/09/26 18:45 編集

    ※注記
    一部修正をいれましたが、日付をつかって計算している限りどうしてもバグが残ります
    計算根拠を少し調製する必要があるかもしれません

    ※調整版あげておきました

    キャンセル

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

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

関連した質問

同じタグがついた質問を見る