webデザインのサンプル集。
〽️ webデザインで「こうしたい」ときのホームです。
「「3// 一定時間おきに実行」」 let a = setInterval(function,delay); 「「3// 一時停止」」 clearInterval(a); 「「3// 再開」」 a = setInterval(function,delay);
こんにちは、「ふ」です。
JavaScriptで一定時間ごとに処理を行うsetInterval。今回はその中断と再開を制御する方法について紹介します。
JavaScriptでタイマーなどを実装する場合には、必須のスキルです、ここは押さえておきましょう。記事後半では停止/再開ボタンを使った「実践編」もお伝えします。
setIntervalについて学習中、次のようなコードを目にするかと思います。
function AAA { 「「3//処理」」 } setInterval(AAA,2000);
関数AAAを定義し、setIntervalで2000ms(2秒)おきに実行させています。しかしこれではsetIntervalメソッドを直接呼び出している形なので、一時停止/再開を実装することができません。
動作を制御するためには、インターバルIDを変数に格納する必要があります。
ブラウザ上で行われているsetIntervalなどのタイマー処理は、1つだけとは限りません。複数のタイマー処理を実装しているケースも、もちろん考えられます。
setIntervalを変数に格納すると、その変数にはインターバルを識別するためのinterval IDというものが返されます。
試しに何もしない空の関数を作り、setIntervalで変数に格納してみます。
function empty() { return; } let BBB = setInterval(empty,1000);
変数BBBに格納されているものを調べましょう。
console.log(BBB); 「「3▶︎ 1」」
「1」が出力されました。
interval IDは1以上の整数値を使って発行されます。関数emptyのsetIntervalをもう1つ作ってみます。
let CCC = setInterval(empty,2000); console.log(CCC); 「「3▶︎ 2」」
別のsetIntervalを作成したところ、interval ID「2」が発行されました。
setIntervalを作成すると、inteval IDが発行される。←なぜこんな面倒くさいことをするのか?それは、「実行している関数名ではタイマー処理を特定することができない」からです。
setIntervalでは、1つの関数に対して複数のタイマー処理を作成することもできます。先ほどの例でも関数「empty」のsetIntervalを2つ作りました。
もし、その片方だけを中断したい場合。
関数名をたよりに「emptyのタイマーを止めて!」と命令しても、ブラウザは「どっちの?」となってしまいます。
そこでinterval IDが必要になってきます。
もし同じ関数で複数のsetIntervalを実行していたとしても、個別のIDをつけておけば、「ID〇〇のタイマーを止めて!」と言えばブラウザもすぐ「ああ、こっちのタイマーね!了解。」と目的のsetIntervalを認識→処理してもらうことができます。
それではintervalの停止/再開を行う方法です。
setIntervalのタイマー処理を停止させるには、interval IDに対してclearIntervalを実行します。
let b = setInterval(function,delay) clearInterval(b);
変数bにinterval IDを格納し、clearIntervalでタイマー処理を停止させています。
停止したsetIntervalを再開させるためのメソッドは、JavaScriptでは用意されていません。そのため新規で同じ内容のsetIntervalを作成し、変数に格納してやる必要があります。
clearInterval(b); let b = setInterval(function,delay);
⬆︎のコードは、clearIntervalで停止させたタイマー処理に対して再開を命令しているものです。
新規でsetIntervalを作成しているので、変数bには以前とは別のinterval IDが格納されます。
これを見ただけでは「具体的にどう使うんだ?」となるかもしれません。
次のセクションで、実際に停止/再開の仕組みを実装してみましょう。
実践編です。
一定時間おきに要素をアニメーションさせるsetIntervalを作成し、停止/再開ボタンで操作できるようにしてみましょう。
<div id = "sikaku"></div> <div id = "btnarea"> <img src = "play.svg" 「「1onclick = "play()"」」> <img src = "pause.svg" 「「1onclick = "pause()"」」> </div> <style> #sikaku { width:100px; height:100px; background-color:crimson; margin:10% auto; } #btnarea { width:30%; margin:0 auto; display:flex; gap:40%; } #btnarea img { width:30%; } </style>
正方形の要素に色を付け、その下にplayボタンとpauseボタンを配置します。
ボタンにはそれぞれ、onclick属性で関数「play」と「pause」を呼び出すようにしました。
紅色正方形に対し、90°回転するアニメーションを仕込みます。
const sikaku1 = document.getElementById("sikaku"); const options = {duration:500}; const keyframes = [ {transform:"rotate(0deg)"}, {transform:"rotate(90deg)"} ]; function 「「1rotate()」」 { sikaku.animate(keyframes,options); }
アニメーションの実装内容については今回は省略しますが、関数「rotate」で実行できるようにしています。
関数「rotate」を1s毎に実行させてみましょう。
let iv_id = setInterval(rotate,1000);
変数「iv_id」にsetIntervalのinterval IDを格納しました。もし初期段階でタイマー処理をさせたくない場合には、
let iv_id;
と、 変数宣言だけにしておきます。
今回は「はじめからタイマー処理が実行されている場合」ということで進めていきます。
setIntervalが実行されています。
pauseボタンとplayボタンをクリックしたときに発動する関数「play」「pause」を実装しましょう。
「「3// 一時停止」」 function pause() { clearInterval(iv_id); } 「「3// intervalを再開」」 function play() { iv_id = setInterval(rotate,1000); }
結果がこちら⬆︎。
pauseボタンについてはちゃんと機能し、intervalを中断させることができています(実際にクリックしてみてください)。
一方playボタン。一見、ちゃんとできているように見えて、実はこれではダメなんです。
playボタンだけを何度か連続でクリックしてみてください。
setIntervalが何重にも作成され、収拾が付かなくなってしまいます(もう一度観察するにはページを再読み込みしてください)。
playボタンをクリックするたび、最新で発行されたinterval IDが変数「iv_id」に代入し直されてはいるのですが、ブラウザ内にはこれまでに作成したsetIntervalがどんどん蓄積されていくのです。
play関数で新しいsetIntervalが生成される前に、以前のsetIntervalをキャンセルするようにしましょう。関数の内容を書き換えます。
function play() { 「「3// intervalがすでに有るのなら、それはキャンセル。」」 if(iv_id) { clearInterval(iv_id); } 「「3// あらためてintervalを作成」」 iv_id = setInterval(rotate,1000); }
これでOKです。playボタンを連続してクリックしても、setIntervalが蓄積することはなくなりました。
最後までお読みくださり、ありがとうございました。
今回紹介したsetIntervalの停止と再開。「ふ」も理屈ではわかっていたものの、記事作成にあたりあらためて実装しようとすると、中々に試行錯誤してしまいました。
「学習したものを実装へ落とし込む」ことができてから、初めて自分のスキルとして追加できるのでしょうね。「知識を得た」だけでは満足してはいけない、と少し反省した「ふ」でありました。
みなさんもsetIntervalの停止/再開ボタンを作って、実際に試してみてください←言えた義理ではない
ではまた〜 ♬
ベクターグラフィック、web、ガジェットなど。役立つ情報や観ていてたのしいページを書いていきたいと思います。