作ったもの
タイマー
使った技術
html, css, javascript
リンク
機能概要
- カウントダウンできる
- 測りたい時間を設定できる
- 時間が経過したらアラームが鳴る
- 途中でカウントダウンをストップできる
- ストップした後、キャンセルボタンを押すとセットした時間に戻る
仕様
項目定義
タイマー
- 時間(hours)
- min: 0
- MAX: 23
- 分(minutes)
- min: 0
- MAX: 59
- 秒(seconds)
- min: 0
- MAX: 59
ボタン定義
- Start
- hours ≠ 0 かつ minutes ≠ 0 かつ seconds ≠ 0のとき、Start ボタンを押下すると、カウントダウンが始まる
- hours = 0 かつ minutes = 0 かつ seconds = 0のとき、Start ボタンを押下しても、画面上何も変化は起きない
- ボタンを押下してカウントダウンが始まると、Stopボタンに変わる
- Stop
- カウントダウンが実行中のとき、ボタンを押下するとカウントダウンが中断する
- Stopボタンが押下されると、自動的にRestartボタンに変わる
- Restart
- カウントダウンが中断中のとき、ボタンを押下するとカウントダウンが再開する
- Restartボタンが押下されると、自動的にStopボタンに変わる
- Reset
- カウントダウン開始前、または実行中は、ボタンを押下できず、背景がグレーになっている
- Stopボタンを押してカウントダウンが止まっているとき、ボタンの背景が青になり、押下できるようになる
- Resetボタンを押すと、以下の通りの動作となる
- タイマーがセレクトボックスに戻り、値は0時間0分0秒に戻る
- RestartボタンがStartボタンに戻る
- Resetボタンは背景がグレーになり、押下できなくなる
詳細設計
変数
- second ... セレクトボックスに入力された秒の値を取得
- minute ... セレクトボックスに入力された分の値を取得
- hour ... セレクトボックスに入力された時間の値を取得
- s ... secondを数値に変換して格納
- m ... minuteを数値に変換して格納
- h ... hourを数値に変換して格納
- time ... カウントダウン用変数 (s, m, hを合計して秒数に変換)
関数
-
startCount()
- 時間をセレクトボックスから設定し、スタートボタンを押したときに動作する
- セレクトボックスの~時間 ~分 ~秒の数値をそれぞれdocument.getElementByIdで取得し、変数h, m, sに格納
- 変数h, m, sを通して設定された時間を秒数に計算し直し、変数timeに格納
- countStart()を呼び出し
-
countStart()
- timeが0以上の時:
- changeButtonToStopを呼び出す (StartボタンをStopボタンに変更する)
- 時間表示を上書く
- countEverySecを定義し、setInterval()を格納
- 1000ミリ秒ごとに、関数countDown()を実行する
- timeが0以上の時:
-
countDown()
- time>0のとき
- timeが1減少する
- 変数h, m, sの値を上書き
- h (時間) = time/3600(切り捨て)
- m (分) = time/60(切り捨て) - h×60
- s (秒) = time-h3600-m60
- それ以外のとき
- 繰り返し動作(countEverySec)を終了する
- alertで”Time up!”という文字列を表示させる
- タイムアップ時の音声を鳴らす
- タイマー表示をセレクトボックスに戻す
- StopボタンをStartボタンに戻す
- time>0のとき
-
stopCount()
- Stopボタンが押されたときに実行される
- 繰り返し動作(countEverySec)を終了する
- 2つ配置されているボタンを"Restart"ボタン、"Reset"ボタンに変える (=StopボタンをRestartボタンに変える)
-
changeButtonToStart()
- 2つ配置されているボタンを"Start"ボタン、"Reset"ボタンに変える
-
changeButtonToStop()
- 2つ配置されているボタンを"Stop"ボタン、"Reset"ボタンに変える
-
restartCount()
- カウントダウンがStopされ、Restartボタンが押されたときに実行
- countStart()を呼び出す
-
reviseCountInput()
- タイマーをカウントダウン表示からセレクトボックス表示に変更する
- changeButtonToStart()を呼び出す
ソース
html
timer.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Timer</title>
<link rel="stylesheet" type="text/css" href="style/timer.css">
<link rel="shortcut icon" href="img/favicon.ico">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="text/javascript" src="js/timer.js"></script>
</head>
<body>
<div class="top_area"></div>
<div class="name">Timer</div>
<div class="middle_area1"></div>
<div id="timer">
<select id="hours" class="timer_contents">
<option>0</option>
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
<option>6</option>
<option>7</option>
<option>8</option>
<option>9</option>
<option>10</option>
<option>11</option>
<option>12</option>
<option>13</option>
<option>14</option>
<option>15</option>
<option>16</option>
<option>17</option>
<option>18</option>
<option>19</option>
<option>20</option>
<option>21</option>
<option>22</option>
<option>23</option>
</select>
<p class="timer_contents"> 時間</p>
<select id="minutes" class="timer_contents">
<option>0</option>
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
<option>6</option>
<option>7</option>
<option>8</option>
<option>9</option>
<option>10</option>
<option>11</option>
<option>12</option>
<option>13</option>
<option>14</option>
<option>15</option>
<option>16</option>
<option>17</option>
<option>18</option>
<option>19</option>
<option>20</option>
<option>21</option>
<option>22</option>
<option>23</option>
<option>24</option>
<option>25</option>
<option>26</option>
<option>27</option>
<option>28</option>
<option>29</option>
<option>30</option>
<option>31</option>
<option>32</option>
<option>33</option>
<option>34</option>
<option>35</option>
<option>36</option>
<option>37</option>
<option>38</option>
<option>39</option>
<option>40</option>
<option>41</option>
<option>42</option>
<option>43</option>
<option>44</option>
<option>45</option>
<option>46</option>
<option>47</option>
<option>48</option>
<option>49</option>
<option>50</option>
<option>51</option>
<option>52</option>
<option>53</option>
<option>54</option>
<option>55</option>
<option>56</option>
<option>57</option>
<option>58</option>
<option>59</option>
</select>
<p class="timer_contents"> 分</p>
<select id="seconds" class="timer_contents">
<option>0</option>
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
<option>6</option>
<option>7</option>
<option>8</option>
<option>9</option>
<option>10</option>
<option>11</option>
<option>12</option>
<option>13</option>
<option>14</option>
<option>15</option>
<option>16</option>
<option>17</option>
<option>18</option>
<option>19</option>
<option>20</option>
<option>21</option>
<option>22</option>
<option>23</option>
<option>24</option>
<option>25</option>
<option>26</option>
<option>27</option>
<option>28</option>
<option>29</option>
<option>30</option>
<option>31</option>
<option>32</option>
<option>33</option>
<option>34</option>
<option>35</option>
<option>36</option>
<option>37</option>
<option>38</option>
<option>39</option>
<option>40</option>
<option>41</option>
<option>42</option>
<option>43</option>
<option>44</option>
<option>45</option>
<option>46</option>
<option>47</option>
<option>48</option>
<option>49</option>
<option>50</option>
<option>51</option>
<option>52</option>
<option>53</option>
<option>54</option>
<option>55</option>
<option>56</option>
<option>57</option>
<option>58</option>
<option>59</option>
</select>
<p class="timer_contents"> 秒</p>
</div>
<div class="middle_area2"></div>
<div class="buttons" id="buttons">
<input type="button" class="button" id="startButton" value="Start" onclick=startCount()>
<input type="button" class="button" id="resetButton" value="Reset" onclick=resetCount() disabled="true">
</div>
<audio id="timeUp" preload="auto">
<source src="sound/alarm.mp3" type="audio/mp3">
</audio>
<!-- To avoid mobile audio issue -->
<iframe src="sound/500-milliseconds-of-silence.mp3" allow="autoplay" id="silenceAudio" style="display:none"></iframe>
</body>
</html>
css
timer.css
body{
margin: 0px;
font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
color: #636363;
}
.top_area {
height: 50px;
background-color: #FFFFFF;
}
.name{
font-size: 28px;
text-align: center;
}
.middle_area1{
height: 50px;
background-color: #FFFFFF;
}
#timer {
font-size: 32px;
text-align: center;
}
.timer_contents{
display: inline-block;
font-size: 24px;
}
.middle_area2{
height: 20px;
background-color: #FFFFFF;
}
.buttons{
text-align: center;
}
.button:enabled{
display: inline-block;
width: 80px;
height: 30px;
background: #668ad8;
margin: 0px 8px;
font-size: 16px;
color: #FFFFFF;
border-radius: 6px;
border-bottom: solid 4px #627295;
}
.button:disabled{
display: inline-block;
width: 80px;
height: 30px;
background: #a0a0a0;
margin: 0px 8px;
font-size: 16px;
color: #FFFFFF;
border-radius: 6px;
border-bottom: solid 4px #627295;
}
js
timer.js
function startCount(){
const second = document.getElementById("seconds").value;
const minute = document.getElementById("minutes").value;
const hour = document.getElementById("hours").value;
s = Number(second);
m = Number(minute);
h = Number(hour);
time = h*3600+m*60+s;
console.log(h*3600+m*60+s);
countStart();
}
function countStart(){
if (time>0) {
changeButtonToStop();
document.getElementById('timer').innerHTML = '<div id="timer">' + h + "時間 " + m +"分 " + s +"秒" + '</div>';
countEverySec = setInterval(countDown, 1000);
}
}
function countDown(){
if (time>0) {
time --;
h = Math.floor(time/3600);
m = Math.floor(time/60)-h*60;
s = time-h*3600-m*60;
document.getElementById('timer').innerHTML = '<div id="timer">' + h + "時間 " + m +"分 " + s +"秒" + '</div>';
} else {
clearInterval(countEverySec);
document.getElementById("timeUp").play();
alert("Time up!");
reviseCountInput();
changeButtonToStart();
}
}
function stopCount(){
clearInterval(countEverySec);
document.getElementById("buttons").innerHTML = '<div class="buttons"><input type="button" class="button" id="restartButton" value="Restart" onclick=restartCount()><input type="button" class="button" id="resetButton" value="Reset" onclick=resetCount()></div>';
}
function changeButtonToStop(){
document.getElementById("buttons").innerHTML = '<div class="buttons"><input type="button" class="button" id="stopButton" value="Stop" onclick=stopCount()><input type="button" class="button" id="resetButton" value="Reset" onclick=resetCount() disabled="true"></div>';
}
function changeButtonToStart(){
document.getElementById("buttons").innerHTML = '<div class="buttons"><input type="button" class="button" id="startButton" value="Start" onclick=startCount()><input type="button" class="button" id="resetButton" value="Reset" onclick=resetCount() disabled="true"></div>';
}
function restartCount(){
countStart();
}
function resetCount(){
clearInterval(countEverySec);
reviseCountInput();
}
function reviseCountInput(){
document.getElementById("timer").innerHTML = '<div id="timer"><select id="hours" class="timer_contents"><option>0</option><option>1</option><option>2</option><option>3</option><option>4</option><option>5</option><option>6</option><option>7</option><option>8</option><option>9</option><option>10</option><option>11</option><option>12</option><option>13</option><option>14</option><option>15</option><option>16</option><option>17</option><option>18</option><option>19</option><option>20</option><option>21</option><option>22</option><option>23</option></select>'+' '+'<p class="timer_contents">時間</p>'+' '+'<select id="minutes" class="timer_contents"><option>0</option><option>1</option><option>2</option><option>3</option><option>4</option><option>5</option><option>6</option><option>7</option><option>8</option><option>9</option><option>10</option><option>11</option><option>12</option><option>13</option><option>14</option><option>15</option><option>16</option><option>17</option><option>18</option><option>19</option><option>20</option><option>21</option><option>22</option><option>23</option><option>24</option><option>25</option><option>26</option><option>27</option><option>28</option><option>29</option><option>30</option><option>31</option><option>32</option><option>33</option><option>34</option><option>35</option><option>36</option><option>37</option><option>38</option><option>39</option><option>40</option><option>41</option><option>42</option><option>43</option><option>44</option><option>45</option><option>46</option><option>47</option><option>48</option><option>49</option><option>50</option><option>51</option><option>52</option><option>53</option><option>54</option><option>55</option><option>56</option><option>57</option><option>58</option><option>59</option></select>'+' '+'<p class="timer_contents">分</p>'+' '+'<select id="seconds" class="timer_contents"><option>0</option><option>1</option><option>2</option><option>3</option><option>4</option><option>5</option><option>6</option><option>7</option><option>8</option><option>9</option><option>10</option><option>11</option><option>12</option><option>13</option><option>14</option><option>15</option><option>16</option><option>17</option><option>18</option><option>19</option><option>20</option><option>21</option><option>22</option><option>23</option><option>24</option><option>25</option><option>26</option><option>27</option><option>28</option><option>29</option><option>30</option><option>31</option><option>32</option><option>33</option><option>34</option><option>35</option><option>36</option><option>37</option><option>38</option><option>39</option><option>40</option><option>41</option><option>42</option><option>43</option><option>44</option><option>45</option><option>46</option><option>47</option><option>48</option><option>49</option><option>50</option><option>51</option><option>52</option><option>53</option><option>54</option><option>55</option><option>56</option><option>57</option><option>58</option><option>59</option></select>'+' '+'<p class="timer_contents">秒</p></div>'
changeButtonToStart();
}
参考にしたリンク
- 1秒ごとに同じ動作を実行する
- javascript - setInterbal(), clearInterbal())
- Resetボタンの押下可能/不可によって表示を出しわける
- css - enabled/disabled
- ブラウザを使って音を出す
- html5 - audio
- タイマー音 フリー素材
解決できていないこと
タイムアップ時の音に関して、PCので実行した際には出るが、iPhoneのSafari, Chromeだと出ない。
以下サイトを参考に実装しているが、上記問題は未解決。
https://webty.jp/staffblog/production/post-907/
そもそもクリック等をトリガーとしないと、iPhoneではブラウザから音が出ない仕組みの様子。