今回はJavaScriptでストップウォッチを作成しました。
シンプルでサンプル・解説ありなので、初心者のJavaScriptの勉強用に良かったら作成してみてください♪
はじめに
まずはストップウォッチの機能を考えます。
今回は以下の機能を持たせて実装しました。
- 時間を計測する
- ボタン:スタート、ストップ、リセット
※ 各ボタンを押すと各ボタンの有効・無効を判定 - 一度ストップしてから再度スタートすると継続して時間を計測
- リセットを押すと”00:00.000″表示となりリセットされる
実際に作成したイメージ図がこちらです。
実装内容(フロー)
次に箇条書きで処理フローを記述します。
- ボタンやタイマーの各要素を変数に設定
- スタートボタン押下時:
- 時間を計測して表示
- スタートボタンを無効
- ストップ、リセットボタンを有効
- ストップボタン押下時:
- 時間計測をストップし、停止時間を保持
- 停止時間を保持
- スタート、リセットボタンを有効
- ストップボタンを無効
- リセットボタン押下時:
- 時間計測をストップし、時間計測に使用する変数や表示時間を初期化
- スタートボタンを有効
- ストップ、リセットボタンを無効
この流れで実際にコーディングを進めていきます。
HTML
まずはHTMLを作成していきます。
作成しているのは、以下の2つです。
- 計測時間の表示
- スタート・ストップ・リセットボタン
<body>
<div class="wrapper">
<!-- 計測時間を表示 -->
<div id="time">00:00.000</div>
<div>
<!-- スタート・ストップ・リセットボタン -->
<button id="start" onclick="start()">Start</button>
<button id="stop" onclick="stop()" disabled>Stop</button>
<button id="reset" onclick="reset()" disabled>Reset</button>
</div>
</div>
</body>
CSS
次にCSSでスタイルを決定します。
この辺りは好きなようにカスタマイズをしていただいて良いと思います!
特に記載するところはありませんが、
強いて言えばボタンは有効時、hoverすると色変化、カーソル変化。無効時は色変化のスタイルを設定しています。
@charset "utf-8";
/*全体*/
.wrapper{
font-family: arial, sans-serif;
max-width: 600px;
margin: 0 auto;
color: #666;
text-align: center;
}
/* 時間表示 */
#time{
font-size: 60px;
margin: 20px 0;
}
/*ボタン*/
button {
padding: 20px 0;
font-size: 30px;
display: inline-block;
padding: .8rem 1.6rem;
border: none;
color: #FFF;
background-color: #B78D4A;
border-radius: 15px;
}
button:hover {
cursor: pointer;
background-color: #D4BB92;
}
button:disabled {
cursor: default;
background-color: #D4BB92;
}
JavaScript
JavaScriptのコードと解説をしていきます。
コード
次項で詳しく解説していますが、コメントでも多少記述しています。
コピペも可能です!
var startButton; // startボタン
var stopButton; // stopボタン
var resetButton; // resetボタン
var showTime; // 表示時間
var timer; // setinterval, clearTimeoutで使用
var startTime; // 開始時間
var elapsedTime = 0; // 経過時間
var holdTime = 0; // 一時停止用に時間を保持
window.onload = function () {
startButton = document.getElementById("start");
stopButton = document.getElementById("stop");
resetButton = document.getElementById("reset");
showTime = document.getElementById("time");
}
// スタートボタン押下時
function start(){
// 開始時間を現在の時刻に設定
startTime = Date.now();
// 時間計測
measureTime();
startButton.disabled = true;
stopButton.disabled = false;
resetButton.disabled = false;
}
// ストップボタン押下時
function stop(){
// タイマー停止
clearInterval(timer);
// 停止時間を保持
holdTime += Date.now() - startTime;
startButton.disabled = false;
stopButton.disabled = true;
resetButton.disabled = false;
}
// リセットボタン押下時
function reset(){
// タイマー停止
clearInterval(timer);
// 変数、表示を初期化
elapsedTime = 0;
holdTime = 0;
showTime.textContent = "00:00.000";
startButton.disabled = false;
stopButton.disabled = true;
resetButton.disabled = true;
}
// 時間を計測(再帰関数)
function measureTime() {
// タイマーを設定
timer = setTimeout(function () {
// 経過時間を設定し、画面へ表示
elapsedTime = Date.now() - startTime + holdTime;
showTime.textContent = new Date(elapsedTime).toISOString().slice(14, 23);
// 関数を呼び出し、時間計測を継続する
measureTime();
}, 10);
}
解説
先述したコードに対して細かく解説していきます!
・グローバル変数の定義
var startButton; // startボタン
var stopButton; // stopボタン
var resetButton; // resetボタン
var showTime; // 表示時間
var timer; // setinterval, clearTimeoutで使用
var startTime; // 開始時間
var elapsedTime = 0; // 経過時間
var holdTime = 0; // 一時停止用に時間を保持
コメントでそれぞれ記載していますが、使用する変数を宣言します。
1~4行がボタン、計測時間の表示でこの後HTMLの要素を設定します。
5~9行が時間の計測に使用する変数です。
・ページ読み込み後、変数にHTML要素を設定
window.onload = function () {
startButton = document.getElementById("start");
stopButton = document.getElementById("stop");
resetButton = document.getElementById("reset");
showTime = document.getElementById("time");
}
ページ読み込み後、ボタンや計測時間の表示のidを指定して各変数にHTML要素を設定します。
・スタートボタン押下時に呼ばれる関数:start()
// スタートボタン押下時
function start(){
// 開始時間を現在の時刻に設定
startTime = Date.now();
// 時間計測
measureTime();
startButton.disabled = true;
stopButton.disabled = false;
resetButton.disabled = false;
}
スタートボタン押下時に呼ばれる関数です。
startTime = Date.now();
時間計測に使用する[開始時間]を変数に設定します。
measureTime();
次に時間計測を行う関数を呼び出します。
時間計測に関しては関数の説明で詳しく説明します。
最後にスタートボタンを無効、ストップ、リセットボタンを有効にします。
・ストップボタン押下時に呼ばれる関数:stop()
// ストップボタン押下時
function stop(){
// タイマー停止
clearInterval(timer);
// 停止時間を保持
holdTime += Date.now() - startTime;
startButton.disabled = false;
stopButton.disabled = true;
resetButton.disabled = false;
}
ストップボタン押下時に呼ばれる関数です。
clearInterval(timer);
時間計測に使用しているタイマーを停止します。
holdTime += Date.now() – startTime;
一度ストップを押下して再度スタートボタンを押下した際、続きから時間を計測するため、停止時間を保持します。
最後にスタート、リセットボタンを有効、ストップボタンを無効にします。
・リセットボタン押下時に呼ばれる関数:reset()
// リセットボタン押下時
function reset(){
// タイマー停止
clearInterval(timer);
// 変数、表示を初期化
elapsedTime = 0;
holdTime = 0;
showTime.textContent = "00:00.000";
startButton.disabled = false;
stopButton.disabled = true;
resetButton.disabled = true;
}
ストップボタン押下時に呼ばれる関数です。
clearInterval(timer);
時間計測に使用しているタイマーを停止します。
elapsedTime = 0;
holdTime = 0;
showTime.textContent = “00:00.000”;
時間計測に使用する変数や表示時間を初期化します。
最後にスタートボタンを有効、ストップ、リセットボタンを無効にします。
・時間を計測する関数(再帰関数):measureTime()
// 時間を計測(再帰関数)
function measureTime() {
// タイマーを設定
timer = setTimeout(function () {
// 経過時間を設定し、画面へ表示
elapsedTime = Date.now() - startTime + holdTime;
showTime.textContent = new Date(elapsedTime).toISOString().slice(14, 23);
// 関数を呼び出し、時間計測を継続する
measureTime();
}, 10);
}
時間を計測する関数です。
4~11行目まででタイマーを設定します。
elapsedTime = Date.now() – startTime + holdTime;
計測時間を計算します。
[現在の時刻] – [開始時間] + [保持している時間]で導き出されます。
startTimeはスタートボタン押下時、holdTimeはストップボタンを押下時に設定しています。
showTime.textContent = new Date(elapsedTime).toISOString().slice(14, 23);
計算した計測時間を表示します。
toISOString():ISO形式の文字列で常にYYYY-MM-DDTHH:mm:ss.sssZ形式を返します。
slice(14, 23):先頭を0として14~23文字目までを取得しているので、
[YYYY-MM-DDTHH:mm:ss.sssZ]の赤線(赤文字)がshowTime.textContentに渡されます。
measureTime();
処理中に自身を呼び出します。
これでストップボタンが押されるまで時間計測が行われます。
デモ
こちらがデモページになります。
良かったら試してみてください♪