フーノページ

setInterval(一定時間ごとの処理)の中断と再開。





webデザインのサンプル集。

〽️ webデザインで「こうしたい」ときのホームです。

syntax。


「「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を変数に格納する必要があります。

interval 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」が発行されました。

なぜIDが必要なのか。

setIntervalを作成すると、inteval IDが発行される。←なぜこんな面倒くさいことをするのか?それは、「実行している関数名ではタイマー処理を特定することができない」からです。
setIntervalでは、1つの関数に対して複数のタイマー処理を作成することもできます。先ほどの例でも関数「empty」のsetIntervalを2つ作りました。

インターバルIDがない状態 もし、その片方だけを中断したい場合。
関数名をたよりに「emptyのタイマーを止めて!」と命令しても、ブラウザは「どっちの?」となってしまいます。

インターバルIDを使って参照 そこでinterval IDが必要になってきます。
もし同じ関数で複数のsetIntervalを実行していたとしても、個別のIDをつけておけば、「ID〇〇のタイマーを止めて!」と言えばブラウザもすぐ「ああ、こっちのタイマーね!了解。」と目的のsetIntervalを認識→処理してもらうことができます。

停止はclearInterval、再開は新規interval。

それではintervalの停止/再開を行う方法です。

clearInterval。

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、ガジェットなど。役立つ情報や観ていてたのしいページを書いていきたいと思います。