簡単なコードでラップ機能付きストップウォッチを作る方法です。
DEMO
HTML
始めに以下のHTMLを書きます。
<div id="wrap"> <div id="output"> <div id="time"></div> </div> <ul id="btns" class="clearfix"> <li id="startstop">START</li> <li id="reset">RESET</li> </ul> <ul id="lap" class="clearfix"> </ul> </div>
ポイント
タイム<div id="time"></div>
とラップ<ul id="lap" class="clearfix"></ul>
内はJavaScriptで生成した要素を挿入するため、ここでは空の状態としています。
CSS
次に以下のCSSを書きます。
* { box-sizing: border-box; } body { background: #08233E; color: #fff; font-family: 'Orbitron', sans-serif; margin: 0; text-align: center; } .clearfix:after { content: ""; clear: both; display: block; } #output { background: #0C555D; font-size: 44px; padding: 20px 0; } ul { list-style: none; margin: 0; padding: 0; } #btns li { /* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#7d7e7d+0,242424+100 */ background: #7d7e7d; /* Old browsers */ background: -moz-linear-gradient(top, #7d7e7d 0%, #242424 100%); /* FF3.6-15 */ background: -webkit-linear-gradient(top, #7d7e7d 0%, #242424 100%); /* Chrome10-25,Safari5.1-6 */ background: linear-gradient(to bottom, #7d7e7d 0%, #242424 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */ filter: progid: DXImageTransform.Microsoft.gradient( startColorstr='#7d7e7d', endColorstr='#242424', GradientType=0); /* IE6-9 */ cursor: pointer; float: left; padding: 20px 0; width: 50%; } #btns li:first-child { border-right: 1px solid #333; } #lap li { border-bottom: 1px solid #2C5379; padding: 15px 0; }
CSSではストップウォッチの見た目を作っています。
JavaScript
最後に以下のJavaScriptを書きます。
(() => { let timer, i = 0, count = 0; const time = document.getElementById('time'), lapList = document.getElementById('lap'), resetBtn = document.getElementById('reset'), startStop = document.getElementById('startstop'); function format(num) { let sec = num / 10; let min = Math.floor(sec / 60); sec = (sec % 60).toFixed(1); let hour = Math.floor(min / 60); min = min % 60; if (sec < 10) { sec = `0${sec}`; //10秒(二桁)になるまで0を付けて二桁に } if (min < 10) { min = `0${min}`; } if (hour < 10) { hour = `0${hour}`; } return `${hour}:${min}:${sec}`; } function print() { time.innerText = format(count); } function stop() { clearInterval(timer); } function lap() { i++; const li = document.createElement('li'); lapList.appendChild(li); li.innerHTML = 'LAP' + i + ' ' + '/' + ' ' + format(count); } function switcher() { if (startStop.classList.contains('on')) { startStop.innerText = 'STOP'; timer = setInterval(() => { count++; time.innerText = format(count); }, 100); } else { startStop.innerText = 'START'; resetBtn.innerText = 'RESET'; stop(); } } function reset() { stop(); startStop.innerText = 'START'; startStop.classList.remove('on'); count = 0; time.innerText = format(count); lapList.textContent = null; } print(); startStop.onclick = function() { this.classList.toggle('on'); resetBtn.innerText = 'LAP'; resetBtn.classList.toggle('on'); switcher(); } resetBtn.onclick = function() { if (this.classList.contains('on')) { lap(); } else { reset(); } } })();
JavaScriptでは以下のことを行っています。
format関数を定義する
format
関数は引数に渡された値count
を、デジタル表記(00:00:00.0)に変換する関数です。
デジタル表記は時間:分:秒となり、時間はhour
、分はmin
、秒はsec
としています。
sec
、min
、hour
はそれぞれ以下のようにして求めます。
sec
num
を10で割ることで、小数にしています。num
には、後に登場するtimer
によって、100ミリ秒つまり0.1秒毎に1カウントされたcount
が次々と代入されていきます。
しかし、このままでは初期表示が00:00:00で、STARTを押したときにいきなり00:00:00.0と表示されるため不自然な表示となります。
このようなことを防ぐために、事前にsec
を60で割った余りに対してtoFixed(1)
を実行し、小数点以下第1位までの表記にします。これによって初期表示から00:00:00.0となります。
続けて、(sec%60)
(sec
を60で割った余り)とすることで、小数点超えのカウント表示(00.0の00の部分)を0以上60未満とし、60以上をカウント表示させないようにしています。なので、60に到達したら0に戻し、そこからまた60までカウントしていきます。
これは、一般に私たちが使っているストップウォッチは70,80...と表示されないことや、小数点超えのカウント表示を二桁までに保つための処理でもあります。
最後に、小数点以上の表記の前に、10秒つまり二桁になるまで0を付けておきます。
min
min
は分を示し、デジタル表記の中央00の部分です。1分は60個の1秒なので(で成り立っているので)、秒sec
を60で割り、60個に分けています。更に、Math.floor
で小数点以下を削除しています。
更に、前述のsec
と同様に、min
にmin%60を上書きすることで、カウントの表記を00以上60未満としています。 また、これも前述の
sec`と同様に、小数点以上の表記の前に、10分つまり二桁になるまで0を付けておきます。
hour
hour
は時間を示し、デジタル表記の左端00の部分です。1時間は60個の1分でできているので、1時間は60分なので、1分/60分つまり60分のうちの1分で、min/60
となります。更に、Math.floor
で小数点以下を削除しています。
stop関数を定義する
タイマーを止めるstop
関数を定義します。この関数はストップボタンかリセットボタンが押されたときに実行されます。
switcher()
が実行されるとタイムを一時停止し、reset()
が実行されると停止します。
lap関数を定義する
ラップタイムを記録するlap
関数を定義します。
処理の流れ
1. i
はLAPの回数を表しており、lap
関数が実行される度にインクリメントされ、LAP1,LAP2...と記録されていく。
2. document.createElement('li');
でli要素を生成し、lapList
内に挿入する。
3. 生成したli要素内に、LAPの回数とlap
関数が実行されたときのタイムformat
を挿入する。
switcher関数を定義する
switcher
関数を定義します。この関数はstartStop
を押したときに各ボタンの表記をどうすべきかを決めます。
処理の流れ
1. タイムが止まっている状態でstartStop
が押されると、startStop
に.on
クラスが付いてタイムが動くため、ボタンの表記がstopに変わる。
2. setInterval
で0.1秒毎にcount
をインクリメントし、その数値を#time
内に挿入。
3. 動いている状態でstartStop
が押されると、.on
クラスが外れてボタンの表記がSTARTに変わります。そして、stop
関数が実行され、タイムが一時停止します。
reset関数を定義する
ストップウォッチをリセットするreset
関数を定義します。
処理の流れ
1. stop
関数が実行されてタイムが一時停止。
2. startStop
の表記がSTARTに変わる。
3. startStop
から.on
クラスが削除される。
4. count
に0を代入し、タイムをリセットする。
5. リセットされたタイムを#time
要素内に出力する。
6. lapList
内を空にする。
ストップウォッチを操作できるようにする
最後にonClick
イベントにコールバック関数を登録することでストップウォッチが操作できるようになります。
startStop
が押されると実行されるコールバック関数では以下のことをしています。
処理の流れ
1. startStop
に.on
クラスが付いていれば外し、付いていなければ付けます。
2. RESETの表記をLAPに切り替えます。
3. resetBtn
に.on
クラスが付いていれば外し、付いていなければ付けます。この処理は、後に登場するresetBtn
のクリックイベントに関わります。
4. switcher
関数を実行し、1.によってタイムのスタート⇔ストップが行なわれます。
resetBtn
が押されると実行されるコールバック関数では先程startStop
で説明した3.によってlap
関数の実行orreset
関数の実行が行われます。
さいごに
以上で、JavaScriptでラップ機能付きのストップウォッチを作る方法を終わります。