LoginSignup
takuonda
@takuonda

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

ページをロードしたり、閉じて開きなおしても継続的に計測できるようにしたい

解決したいこと

労働時間を記録するようなストップウォッチを作成したいです。ページをロードしたり、閉じて開きなおしても計測している時間が維持され、そのままstartボタンなどの操作で継続的に計測できるようにしたいです。

前提
JSでコーティングをしております。
データをとどめておくために、
saveDataとshowTimeという関数を作成して実現しようとしています。

発生している問題・エラー

発生している問題・エラーメッセージ
ページのロードと再起動によるデータの保存はできているのですが、そこからstartボタンをクリックする操作によって、計測が0から再開してしまします。

該当するソースコード

let [milliseconds, seconds, minutes, hours] = [0, 0, 0, 0];
let [OvertimeMilliseconds, OvertimeSeconds, OvertimeMinutes, OvertimeHours] = [0, 0, 0, 0];
let timerRef = document.querySelector('.timerDisplay');
let overTimeRef = document.querySelector(`.overTimeDisplay`);
let int = null;

document.getElementById('startTimer').addEventListener('click', () => {
    if (int !== null) {
        clearInterval(int);
    }
    int = setInterval(displayTimer, 10);
    saveData();
    showTime();
});

document.getElementById('pauseTimer').addEventListener('click', () => {
    clearInterval(int);
    saveData();
});

document.getElementById('resetTimer').addEventListener('click', () => {
    clearInterval(int);
    [milliseconds, seconds, minutes, hours] = [0, 0, 0, 0];
    timerRef.innerHTML = '00 : 00 : 00';
    saveData();
});

document.getElementById('overtimeReset').addEventListener('click', () => {
    clearInterval(int);
    [OvertimeMilliseconds, OvertimeSeconds, OvertimeMinutes, OvertimeHours] = [0, 0, 0, 0];
    overTimeRef.innerHTML = '00 : 00 : 00';
    saveData();
});

function displayTimer() {
    milliseconds += 10;

    if (milliseconds == 1000) {
        milliseconds = 0;
        seconds++;

        if (seconds == 60) {
            seconds = 0;
            minutes++;

            if (minutes == 60) {
                minutes = 0;
                hours++;
            }
        }
    }


    let h = hours < 10 ? "0" + hours : hours;
    let m = minutes < 10 ? "0" + minutes : minutes;
    let s = seconds < 10 ? "0" + seconds : seconds;


    timerRef.innerHTML = ` ${h} : ${m} : ${s}`;

    if (s >= 8) {
        overtimeDisplayTimer();
    }
saveData();
}

function overtimeDisplayTimer() {
    OvertimeMilliseconds += 10;

    if (OvertimeMilliseconds == 1000) {
        OvertimeMilliseconds = 0;
        OvertimeSeconds++;

        if (OvertimeSeconds == 60) {
            OvertimeSeconds = 0;
            OvertimeMinutes++;

            if (OvertimeMinutes == 60) {
                OvertimeMinutes = 0;
                OvertimeHours++;
            }
        }
    }


    let h = OvertimeHours < 10 ? "0" + OvertimeHours : OvertimeHours;
    let m = OvertimeMinutes < 10 ? "0" + OvertimeMinutes : OvertimeMinutes;
    let s = OvertimeSeconds < 10 ? "0" + OvertimeSeconds : OvertimeSeconds;


    overTimeRef.innerHTML = ` ${h} : ${m} : ${s}`;
    saveData();
}


function saveData() {
    localStorage.setItem("time", timerRef.innerHTML);
    localStorage.setItem("overtime", overTimeRef.innerHTML);
}

function showTime() {
    const savedTime = localStorage.getItem("time");
    const savedOvertime = localStorage.getItem("overtime");
    if (savedTime !== null) {
        timerRef.innerHTML = savedTime;
    }
    if (savedOvertime !== null) {
        overTimeRef.innerHTML = savedOvertime;
    }
}

showTime();

1

2Answer

とりあえずどういう画面でどういう動きをさせたいのかパッと見わからないので、https://codesandbox.io/ とかで、とりあえず最低限でいいので実現したいような画面をエラーが出ても良いんで作ってみると回答を得やすいと思います。

codesandbox
https://codesandbox.io/s/https-qiita-com-takuonda-questions-c028d51dad761b12e7e7-7p43ck

なぜ10msなのか? 1秒単位の再描画なんだから1000=1sで良いのでは?

int = setInterval(displayTimer, 10);

そうすればここは呼び出される度に秒を加算するだけでいいはず

function displayTimer() {
  milliseconds += 10;

  if (milliseconds == 1000) {
    milliseconds = 0;
    seconds++;

    if (seconds == 60) {
      seconds = 0;
      minutes++;

      if (minutes == 60) {
        minutes = 0;
        hours++;
      }
    }
  }
0

Your answer might help someone💌