こんにちは!セミマサです。
今回はJavaScriptを使って入力された秒数が経過したら音を鳴らすタイマーを作ってみました。
デモサイト
今回のデモサイトです。
お借りした効果音
効果音は効果音ラボ様からお借りしました。
ソースコード
HTML
<section>
<div class="timer-box">
<div class="timer-set-box">
<p>1以上の数字を入力してください</p>
<input type="number" id="timer_input">
<button id="timer-button">タイマーセット</button>
</div>
<p id="time"></p>
<p id="warning">入力値が不正です</p>
</div>
</section>
<audio src="sound/tin1.mp3" id = "sound"></audio>
・JavaScriptで参照するために各要素にidを付与しておきます。
・入力欄は数字のみ入れられるようtypeにnumberを指定しています。
・鳴らしたい効果音をaudioタグで埋め込んでいます。
CSS
.timer-box{
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
padding: 32px;
}
.timer-set-box{
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
margin-bottom: 16px;
}
#timer_input{
margin-bottom: 8px;
}
#time{
text-align: center;
}
#warning{
padding: 16px;
margin-top: 8px;
border:1px solid orange;
opacity: 0;
transition: ease-in-out .3s;
}
#warning.is-active{
opacity: 1;
transition: ease-in-out .3s;
}
今回のCSSです。
JavaScript
timer = new Array;
count = 0;
document.getElementById("timer-button").onclick = ()=>{
let output = document.getElementById("timer_input");
let sec = output.value;
var message = document.getElementById("warning");
if(sec === ""){
message.classList.add("is-active");
output.value="";
return false;
}
if(sec <= 0){
message.classList.add("is-active");
output.value="";
return false;
}
message.classList.remove("is-active");
nowDate = new Date();
endDate = new Date(nowDate.getTime() + sec * 1000);
count = sec;
document.getElementById("time").textContent = "あと" + sec + "秒です";
if(timer.length >= 1){
stopTimer();
}
timer.push(setInterval(setTimer,1000));
output.value="";
};
const setTimer = ()=>{
count--;
document.getElementById("time").textContent = "あと" + count + "秒です";
nowDate = new Date();
if(nowDate.getTime() >= endDate.getTime()){
document.getElementById("time").textContent = "時間になりました";
stopTimer();
document.getElementById("sound").play();
}
};
const stopTimer = ()=>{
clearInterval(timer.shift());
}
・配列timerと変数countをグローバルに定義しています。
ボタンクリック時の処理
①:入力された値を変数secに代入します。この時secが空白もしくはマイナスの値だった場合早期リターンし、警告メッセージを表示します。正規の入力が行われた時に警告メッセージを非表示にします。
②:nowDateに現在の時刻を代入し、endDateにタイマーの終了時刻を代入します。終了時刻の計算はエポックミリ秒によるものです。
③:グローバル変数countにsecを代入します。
④:配列timerにsetTimer関数を追加します。setInterval関数によって1秒毎にsetTimer関数が実行されます。
※すでにタイマーが起動中の時に正規の処理が行われた場合、setTimer関数を追加する前にstopTimer関数が呼ばれます。
setTimer関数
メインとなる関数です。
・countのマイナスと文言の更新を行い、nowDateに現在時刻を代入します。
・現在時刻のエポックミリ秒が終了時刻のエポックミリ秒以上の場合、文言の変更・stopTimer関数の実行・効果音の再生をします。
stopTimer関数
タイマーを止める関数です。
・shift()メソッドで配列timerの最初の要素を取り出し、その要素に対してclearInterval関数を実行します。
おわりに
無事動くものが作れました。