この記事では、JavaScriptでタイマーを作成する方法について見ていきたいと思います。
ここで説明する通りにコードを書くことで次にようなタイマーを作成することができます。
HTMLの作成
ここでは、タイマーを操作するためのボタンとタイマーをセットするためのボタンと表示する要素を作成します。
<div class="board">
<div>
<input type="button" id="start" class="inactive" value="開始">
<input type="button" id="stop" class="inactive" value="一時停止">
<input type="button" id="reset" class="inactive" value="リセット">
</div>
<div id="setTimeBtns">
<input type="button" id="addHours" value="時">
<input type="button" id="addMinutes" value="分">
<input type="button" id="addSeconds" value="秒">
</div>
<p id="display"></p>
</div>
CSSの作成
ここでは、CSSでボタンや背景色などのデザインを設定します。
.board {
background-color: aqua;
height: 150px;
width: 230px;
padding: 20px;
margin: 0 auto;
}
#setTimeBtns { margin-top: 10px;}
.inactive { opacity: 50%;}
#display {
padding: 10px;
background-color: #fff;
font-size: 1.4em;
}
.board,#display {
text-align: center;
user-select: none;
border-radius: 5px;
}
以下からはJavaScriptの処理です。
変数の定義
ここでは、あとで使う変数を定義していきます。
let hours;
let hours;
let minutes;
let seconds;
let initial = true;
let running = false;
let timeUp = false;
let display = document.getElementById("display");
let start = document.getElementById("start");
let stop = document.getElementById("stop");
let reset = document.getElementById("reset");
let addHours = document.getElementById("addHours");
let addMinutes = document.getElementById("addMinutes");
let addSeconds = document.getElementById("addSeconds");
※ここで用いているgetElementById()は、HTML要素をIdをキーに取得するメソッドです。
詳しくは以下の記事にて参照していただけます。
JavaScriptのgetElementById()の使い方
時間をリセットする関数の定義
ここでは、時・分・秒をリセットするための関数を定義します。
function resetTime() {
hours = 0;
minutes = 0;
seconds = 0;
}
時間を表示する関数の定義
ここでは、時間を表示する関数を定義します。
function displayTime() {
display.textContent = `${("0" + hours).slice(-2)}:${("0" + minutes).slice(-2)}:${("0" + seconds).slice(-2)}`;
}
ここで用いている("0" + hours).slice(-2)は、文字列「0」に変数「hours」に代入されている数値をつなげて文字列にし、その文字列の末尾から数えて2番目の文字から末尾の文字までを切り取るという意味になります。
そうすることで、2桁の数値を表示にすることができるわけですね。
「minutes」や「seconds」についても同様です。
なお、ここで用いているslice()については以下の記事で解説をしています。
JavaScriptのslice()で文字列の一部を切り抜く方法
カウントダウンをする関数の定義
ここでは、カウントダウンをする関数を定義していきます。
function countDown() {
setTimeout(()=>{
if(!running) {
return;
} else if(seconds > 0) {
seconds--;
displayTime();
} else if(seconds === 0) {
if(minutes > 0) {
minutes--;
seconds = 59;
displayTime();
} else if(minutes === 0) {
if(hours > 0) {
hours--;
minutes = 59;
seconds = 59;
displayTime();
} else if(hours === 0) {
stopped = true;
timeUp = true;
display.textContent = "タイムアップです。";
stop.classList.add("inactive");
}
}
}
countDown();
}, 1000);
}
ここでは、setTimeout()を用いて、変数「running」がfalseであれば「return」で関数を終了させ、そうでなければ、1000ミリ秒(=1秒)毎にcountDown()を実行させるという内容ですね。
●条件分岐は次の通りになります。
・「seconds」が0より大きい場合
→「seconds」から1をマイナス
・「seconds」が0で「minutes」が0より大きい場合
→「minutes」から1をマイナスし、「seconds」に59を代入
・「seconds」が0で、「minutes」が0で「hours」が0より大き場合
→「hours」から1を減算し、「seconds」と「minutes」に59を代入
・「seconds」が0で、「minutes」が0で「hours」が0の場合
→「タイムアップです。」と表示させる。
ボタンをクリックしたときの処理を定義
ここでは、ボタンをクリックしたときに実行される処理を定義していきます。
「start」ボタンをクリックしたときの処理
start.addEventListener("click", () => {
if(initial) {
return;
} else if(running) {
return;
} else {
running = true;
start.classList.add("inactive");
stop.classList.remove("inactive");
reset.classList.add("inactive");
addHours.classList.add("inactive");
addMinutes.classList.add("inactive");
addSeconds.classList.add("inactive");
countDown();
}
});
ここでは、「start」ボタンを押した時、もし変数「initial」が「true」であれば「return」を用いて処理を終了させます。
そうでない場合でも、もし変数「running」が「true」であれば同様に「return」を用いて
処理を終了させます。
上記の2パターンの両方に当てはまらない場合は、「running」を「true」にして「stop」ボタン以外を半透明にしたうえでcountDown()を開始(もしくは再開)させます。
「stop」ボタンをクリックしたときの処理
stop.addEventListener("click", () => {
if(running) {
running = false;
stop.classList.add("inactive");
start.classList.remove("inactive");
reset.classList.remove("inactive");
addHours.classList.remove("inactive");
addMinutes.classList.remove("inactive");
addSeconds.classList.remove("inactive");
} else {
return;
}
});
ここでは、「stop」ボタンを押した時に、もし変数「running」が「true」である場合は「running」を「false」にして「stop」ボタン以外のボタンを不透明にします。
そうでなければ、「return」で処理を終了させます。
「reset」ボタンをクリックしたときの処理
reset.addEventListener("click", () => {
if(running) {
return;
} else if(hours !==0 || minutes !== 0 || seconds !== 0) {
initial = true;
resetTime();
displayTime();
start.classList.add("inactive");
reset.classList.add("inactive");
addHours.classList.remove("inactive");
addMinutes.classList.remove("inactive");
addSeconds.classList.remove("inactive");
}
});
ここでは、「reset」ボタンを押した時に、もし変数「running」が「true」である場合は「return」で処理を終了させます。
そうでなければ、変数「initial」を「true」にし、resetTime()で変数「hours」「minutes」「seconds」の値を全て0にし、「start」「reset」ボタンを半透明にし、「addHours」「addMinutes」「addSeconds」ボタンを不透明にします。
「addHours」ボタンをクリックしたときの処理
addHours.addEventListener("click", () => {
if(running) {
return;
} else {
hours++;
displayTime();
if(hours !== 0 || minutes !== 0 || seconds !== 0) {
initial = false;
start.classList.remove("inactive");
reset.classList.remove("inactive");
}
}
});
ここでは、「addHours」ボタンをクリックした場合の処理を指定します。
その中で、もし変数「running」が「true」である場合は「return」で処理を終了させ、そうでない場合は変数「hours」に1を加算し、displayTime()でディスプレイに時間を表示させ、もし変数「hours」「minutes」「seconds」のどれかが0でない場合は、「start」ボタンと「reset」ボタンを不透明にします。
「addMinutes」ボタンをクリックしたときの処理
addMinutes.addEventListener("click", () => {
if(running) {
return;
} else if(minutes < 59) {
minutes++;
} else {
minutes = 0;
hours++;
}
displayTime();
if(hours !== 0 || minutes !== 0 || seconds !== 0) {
initial = false;
start.classList.remove("inactive");
reset.classList.remove("inactive");
}
});
ここでは、「addMinutes」ボタンをクリックした時の処理を指定します。
その中で、もし変数「running」が「true」であれば、「return」で処理を終了させます。
それ以外の場合で、変数「minutes」が59よりも小さい場合は「minutes」に1を加算し、
そうでない場合は、「minutes」に0を代入し、「hours」に1を加算します。
そしてdisplayTime()でディスプレイに時間を表示させます。
そして、「addHours」と同様に、変数「hours」「minutes」「seconds」のどれかが0でない場合は、「start」ボタンと「reset」ボタンを不透明にします。
「addSeconds」ボタンをクリックしたときの処理
addSeconds.addEventListener("click", () => {
if(running) {
return;
} else if(seconds < 59) {
seconds++;
} else {
if(minutes < 59) {
seconds = 0;
minutes++;
} else {
seconds = 0;
minutes = 0;
hours++;
}
}
displayTime();
if(hours !== 0 || minutes !== 0 || seconds !== 0) {
initial = false;
start.classList.remove("inactive");
reset.classList.remove("inactive");
}
});
ここでは、「addSeconds」ボタンをクリックした時の処理を指定します。
その中で、もし「running」が「true」であれば、処理を終了させます。
そうではなく、もし「seconds」が59よりも小さい場合は「seconds」に1を加算させ、そうではなくもし「seconds」が59以上である場合で「minutes」が59よりも小さい場合は「seconds」に0を代入し、「minutes」に1を加算します。そうでもなく「minutes」が59以上である場合は「seconds」と「minutes」に0を代入し「hours」に1を加算します。
そして、「addHours」「addMinutes」ボタンを押した時と同様に、ディスプレイに時間を表示し、変数「hours」「minutes」「seconds」のどれかが0でない場合は、「start」ボタンと「reset」ボタンを不透明にします。
関数の実行
setTime();
displayTime();
ここでは、最初にページが表示されたときに行われる処理を指定します。
完成
上記で説明したコードをつなぎ合わせると以下のようになります。
let hours;
let minutes;
let seconds;
let initial = true;
let running = false;
let timeUp = false;
let display = document.getElementById("display");
let start = document.getElementById("start");
let stop = document.getElementById("stop");
let reset = document.getElementById("reset");
let addHours = document.getElementById("addHours");
let addMinutes = document.getElementById("addMinutes");
let addSeconds = document.getElementById("addSeconds");
function resetTime() {
hours = 0;
minutes = 0;
seconds = 0;
}
function displayTime() {
display.textContent = `${("0" + hours).slice(-2)}:${("0" + minutes).slice(-2)}:${("0" + seconds).slice(-2)}`;
}
function countDown() {
setTimeout(()=>{
if(!running) {
return;
} else if(seconds > 0) {
seconds--;
displayTime();
} else if(seconds === 0) {
if(minutes > 0) {
minutes--;
seconds = 59;
displayTime();
} else if(minutes === 0) {
if(hours > 0) {
hours--;
minutes = 59;
seconds = 59;
displayTime();
} else if(hours === 0) {
stopped = true;
timeUp = true;
display.textContent = "タイムアップです。";
stop.classList.add("inactive");
}
}
}
countDown();
}, 1000);
}
start.addEventListener("click", () => {
if(initial) {
return;
} else if(running) {
return;
} else {
running = true;
start.classList.add("inactive");
stop.classList.remove("inactive");
reset.classList.add("inactive");
addHours.classList.add("inactive");
addMinutes.classList.add("inactive");
addSeconds.classList.add("inactive");
countDown();
}
});
stop.addEventListener("click", () => {
if(running) {
running = false;
stop.classList.add("inactive");
start.classList.remove("inactive");
reset.classList.remove("inactive");
addHours.classList.remove("inactive");
addMinutes.classList.remove("inactive");
addSeconds.classList.remove("inactive");
} else {
return;
}
});
reset.addEventListener("click", () => {
if(running) {
return;
} else if(hours !==0 || minutes !== 0 || seconds !== 0) {
initial = true;
resetTime();
displayTime();
start.classList.add("inactive");
reset.classList.add("inactive");
addHours.classList.remove("inactive");
addMinutes.classList.remove("inactive");
addSeconds.classList.remove("inactive");
}
});
addHours.addEventListener("click", () => {
if(running) {
return;
} else {
hours++;
displayTime();
if(hours !== 0 || minutes !== 0 || seconds !== 0) {
initial = false;
start.classList.remove("inactive");
reset.classList.remove("inactive");
}
}
});
addMinutes.addEventListener("click", () => {
if(running) {
return;
} else if(minutes < 59) {
minutes++;
} else {
minutes = 0;
hours++;
}
displayTime();
if(hours !== 0 || minutes !== 0 || seconds !== 0) {
initial = false;
start.classList.remove("inactive");
reset.classList.remove("inactive");
}
});
addSeconds.addEventListener("click", () => {
if(running) {
return;
} else if(seconds < 59) {
seconds++;
} else {
if(minutes < 59) {
seconds = 0;
minutes++;
} else {
seconds = 0;
minutes = 0;
hours++;
}
}
displayTime();
if(hours !== 0 || minutes !== 0 || seconds !== 0) {
initial = false;
start.classList.remove("inactive");
reset.classList.remove("inactive");
}
});
resetTime();
displayTime();
コメント