<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style type="text/css">
<!--
body
{
font-size: 16px;
}
div#container
{
margin:0 10%;
border:2px solid gray;
}
div#display
{
padding:0.5em 0;/*親要素の文字サイズを基準としてpaddingを設定*/
text-align: center;
font-size:5em;
/*等幅フォントにしないとtimerの表示がずれる*/
font-family: "メイリオ",monospace !important;
}
div#lap_display
{
font-size:2em;
background-color:silver;
height:400px;
overflow: scroll;
}
div#button_wrapper
{
border:1px solid gray;
text-align: center;
}
div#button_wrapper button
{
font-size: 3em;
}
button#lap:disabled,button#reset:disabled
{
background-color: #ededed;
color:silver;
}
-->
</style>
</head>
<body>
<div id="container">
<div id="display"></div>
<div id="button_wrapper">
<button id="start">
</button>
<button id="lap">
ラップタイム
</button>
<button id="reset">
リセット
</button>
</div>
<div id="lap_display">
</div>
</div>
<script>
//html要素の取得
let startButton = document.getElementById("start");
let resetButton = document.getElementById("reset");
let lapButton = document.getElementById("lap");
let testButton = document.getElementById("test");
let display = document.getElementById("display");
let lap_display = document.getElementById("lap_display");
//lapボタンの初期値セット
lapButton.setAttribute("disabled" , true);
let lapNumber = 0;
//スイッチ用のモード
let mode = "stop";
let interval_1;
let startTime;
let accumTime = 0;//累積時間
let display_ms = 0;
//タイマーの初期値をセット
let timeTemplate = "00:00:00:000";
//display.textcontentへのprevious_accumTimeのセット
display.textContent = localStrageDefaultValueSet();
//ボタンの内容物をトグルする
let startButtonTemplate_start = "スタート";
let startButtonTemplate_stop = "ストップ";
//ボタンのデフォルトテキストをセットする
startButton.textContent = startButtonTemplate_start;
//ラップタイム用の配列
//let laptime_arr = [];
startButton.addEventListener("click" , function()
{
switch(mode)
{
case "stop":
mode = "run";
startButton.textContent = startButtonTemplate_stop;
resetButton.setAttribute("disabled" , true);
lapButton.removeAttribute("disabled");
//ここで開始時刻を取得
startTime = Date.now();
interval_1 = setInterval(update ,30);
//ローカルストレージから初期値、あるいは前回終了時の累積値を取り出す
accumTime = Number(localStorage.getItem("previous_accumTime"));
break;
case "run":
startButton.textContent = startButtonTemplate_start;
mode_and_interval_stop();
// #region comment
//let textContent_of_timer = Number(display.textContent);//タイマーを止めた時点でのdisplay.textContentを保存しておく
//accumTime += Date.now() - startTime;//タイマーを止めた時点での累積時間
//タイマーを止めた時点でのaccumTimeをupdate関数内から取り出す
//取り出したdisplay_msをaccumTimeに代入することで、次のスタート時点は途中から加算される
// #endregion
accumTime = display_ms;
//ローカルストレージに今現在の累積時間を保存
localStorage.setItem("previous_accumTime" , accumTime);
break;
}
});
//タイマーをリセット
resetButton.addEventListener("click" , function()
{
display_ms = 0;
accumTime = 0;
display.textContent = timeTemplate;
startButton.removeAttribute("disabled");
//lap関係のリセット
lapNumber = 0;
lap_display.innerHTML = "";
//localStorageのリセット
localStorage.setItem("previous_accumTime" , 0);
});
lapButton.addEventListener("click" , function()
{
lapNumber += 1;
let lap_display_inner = "<span>LAP" + lapNumber + " : " + display.textContent + "</span><br>";
let lap_time = lap_display.insertAdjacentHTML("afterbegin" ,lap_display_inner );
/*
//クリックごとにlaptimeをlocalstrageに保存しておく
laptime_arr.push(lap_display_inner);
localStorage.setItem("setLapTime" , JSON.stringify(laptime_arr));
*/
});
function update()
{
// #region comment
//timerに表示
// 0 + (1500ms - 1000ms)//60msごとにDate.now()が増えていく
//以下のようにaccumTimeにupdate内で加算すると、60ms(setIntervalの設定値)ごとにが加算されてしまうので、stop時に加算する
//accumTime += (Date.now() - startTime);
//1000 +=1000 + (1500 - 1000) = 1500
// 1500 += 1500 +(1600 - 1000) 2100
//2100 += 2100 + (1700 - 1000) = 2800
//update内で加算すると、増え幅が雪だるま式になる
// #endregion
display_ms = accumTime + (Date.now() - startTime);
display.textContent = ms_converter(display_ms);
//タイマーのカウントが24時間を超えたら止める
if(display_ms > 86400000)
{
mode_and_interval_stop();
startButton.setAttribute("disabled" , true);
alert(display_ms);
}
}
//msをストップウォッチの形式に変換
function ms_converter(ms)
{
const date = new Date(ms);
return `${("0" + Math.floor(date/3600000)).slice(-2)}:${("0" + date.getMinutes()).slice(-2)}:${("0" + date.getSeconds()).slice(-2)}:${("0" + date.getMilliseconds()).slice(-3)
}` ;
}
function mode_and_interval_stop()
{
clearInterval(interval_1);
mode = "stop";
//リセットボタン無効化
resetButton.removeAttribute("disabled" , true);
//ラップボタン有効化
lapButton.setAttribute("disabled" , true);
}
//ローカルストレージのデフォルト値をセット
function localStrageDefaultValueSet()
{
//newしてないとgetSecondsなどの関数は使えない
let localStrageDate = new Date(Number(localStorage.getItem("previous_accumTime")));
return ms_converter(localStrageDate);
}
/*
//ラップタイムの保存とリストア
function set_laptime_from_localstrage()
{
let date = JSON.parse(localStorage.getItem("setLapTime"));
for(let i = 0;i < date.length ; i++)
{
lap_display.innerHTML += date[i];
}
}
*/
</script>
</body>
</html>