このページはコミュニティーの尽力で英語から翻訳されました。MDN Web Docsコミュニティーについてもっと知り、仲間になるにはこちらから。
Window: setInterval() メソッド
Baseline Widely available *
This feature is well established and works across many devices and browser versions. It’s been available across browsers since 2015年7月.
* Some parts of this feature may have varying levels of support.
setInterval() はWindow インターフェイスのメソッドで、一定の間隔を置いて関数やコードスニペットを繰り返し呼び出します。
In this article
構文
setInterval(code)setInterval(code, delay)setInterval(func)setInterval(func, delay)setInterval(func, delay, arg1)setInterval(func, delay, arg1, arg2)setInterval(func, delay, arg1, arg2, /* …, */ argN)引数
funcdelayミリ秒が経過するたびに実行する関数です。最初の実行はdelayミリ秒後に行われます。code関数の代わりに文字列を含める構文も許容されており、
delayミリ秒が経過するたびに文字列をコンパイルして実行します。この構文は推奨しません。eval()の使用にセキュリティ上のリスクがあるのと同じ理由です。delay省略可指定した関数またはコードを実行する前にタイマーが待つべき時間をミリ秒 (1/1000 秒) 単位で指定します。指定されなかった場合の既定値は 0 です。
delay値で許される範囲についての詳細は、待ち時間の制約をご覧ください。arg1, …,argN省略可タイマーが満了したときに、func で指定した関数に渡す追加の引数です。
返値
setInterval() メソッドは、呼び出しによって作成されたインターバルタイマーを一意に識別する正の整数(通常は 1 から 2,147,483,647 の範囲)を返します。この識別子は、よく「インターバル ID」と呼ばれ、clearInterval() に渡すことで、指定した関数の反復実行を停止することができます。
同じグローバル環境(特定のウィンドウやワーカーなど)では、元のタイマーがアクティブである限り、インターバル ID は確実に一意となりあり、新しいインターバルタイマーには再利用されません。ただし、グローバル環境が異なると、それぞれ独立したインターバル ID のプールが管理されます。
setInterval() とsetTimeout() は同じ ID プールを共有しており、clearInterval() とclearTimeout() は技術的に入れ替えて使用できることに注意してください。ただし明確さのために、コードを整備するときは混乱を避けるため、常に一致させるようにするべきです。
メモ:引数delay は、符号付き 32 ビット整数に変換されます。IDL における符号付き整数の定義によって、delay は事実上 2147483647ms、およそ 24.8 日に制限されます。
例
>例 1: 基本的な構文
以下の例は、setInterval() の基本的な構文を示します。
const intervalID = setInterval(myCallback, 500, "Parameter 1", "Parameter 2");function myCallback(a, b) { // ここにコードを記述します。 // 引数は完全に省略可能です。 console.log(a); console.log(b);}例 2: 2 つの色を切り替える
以下の例は停止ボタンを押すまで、1 秒おきにflashtext() 関数を呼び出します。
HTML
<div> <h3>Hello World</h3></div><button>開始</button><button>停止</button>CSS
.go { color: green;}.stop { color: red;}JavaScript
// intervalID を格納する変数let intervalId;function changeColor() { // 既にインターバルがセットアップされているかどうかを検査 intervalId ??= setInterval(flashText, 1000);}function flashText() { const oElem = document.getElementById("my_box"); oElem.className = oElem.className === "go" ? "stop" : "go";}function stopTextColor() { clearInterval(intervalId); // 変数から intervalID を解放 intervalId = null;}document.getElementById("start").addEventListener("click", changeColor);document.getElementById("stop").addEventListener("click", stopTextColor);結果
"this" 問題
setInterval() に(もっと言うと他のどんな関数でも)メソッドを渡すと、間違ったthis の値で呼び出されることがあります。この問題はJavaScript リファレンスで詳しく説明しています。
解説
setInterval() によって実行されるコードは、呼び出し元とは別の実行コンテキスト内で実行されます。その結果、呼び出された関数のthis キーワードはwindow (またはglobal)オブジェクトに設定されます。これはsetTimeout を呼び出した関数とはthis の値が異なります。以下の例をご覧ください(ここではsetInterval() ではなくsetTimeout() を使用していますが、どちらのタイマーでも問題は同じです)。
myArray = ["zero", "one", "two"];myArray.myMethod = function (sProperty) { alert(arguments.length > 0 ? this[sProperty] : this);};myArray.myMethod(); // "zero,one,two" と表示myArray.myMethod(1); // "one" と表示setTimeout(myArray.myMethod, 1000); // "[object Window]" と 1 秒後に表示setTimeout(myArray.myMethod, 1500, "1"); // "undefined" と 1.5 秒後に表示// 'this' オブジェクトを .call で渡しても動作しません。// これは、 myArray.myMethod 内の this の値を変更したいのに、// setTimeout 自体の中で this の値が変更されてしまうからです。// 実際、setTimeout のコードはこれがウィンドウオブジェクトであることを期待しているため、エラーになります。setTimeout.call(myArray, myArray.myMethod, 2000); // エラー: "NS_ERROR_XPC_BAD_OP_ON_WN_PROTO: Illegal operation on WrappedNative prototype object"setTimeout.call(myArray, myArray.myMethod, 2500, 2); // 同じエラーこの例でわかるとおり、旧来の JavaScript でコールバック関数にthis オブジェクトを渡す方法はありません。
取りうる解決策
最近の JavaScript ランタイムはすべて(ブラウザーとそそれ以外を含め)、アロー関数とthis 表記と組み合わせると、myArray メソッドの内部にいる場合はsetInterval(() => this.myMethod()) と記述することが可能です。
IE に対応する必要がある場合は、Function.prototype.bind() メソッドを使用すると、与えられた関数へのすべての呼び出しに対してthis として使用する値を指定することができます。これにより、関数が呼び出されたときのコンテキストによってthis が何であるかが不明確な問題を簡単に回避することができます。
使用上のメモ
setInterval() 関数は一般に、アニメーションのように何度も実行される関数のために待ち時間を設定するのに使われます。clearInterval() を使ってインターバルを取り消すことができます。
指定時間後に一度だけ関数を呼び出したい場合には、setTimeout() を使用してください。
待ち時間の制約
setInterval() のコールバックは順番にsetInterval() を呼び出し、最初のインターバルがまだ進行中であっても、別のインターバルを開始させることができます。このことがパフォーマンスに与える潜在的な影響を軽減するために、インターバルが 5 レベルを超えてネストされると、ブラウザーは自動的にインターバルの最小値として 4 ミリ秒を強制するようになります。深くネストされたsetInterval() の呼び出しで 4ms 未満の値を指定しようとすると、 4ms に固定されます。
ブラウザーは、状況によってはさらに厳しい最小間隔値を強制するかもしれませんが、これは一般的なことではありません。また、コールバックの呼び出しの間に経過する実際の時間は、与えられたdelay よりも長いかもしれないことに注意してください。例については待ち時間が指定値より長い理由を参照してください。
実行時間をインターバルより確実に短くする
ロジックの実行時間がインターバル時間より長くなる可能性がある場合は、setTimeout() を使用して名前付き関数を再帰的に呼び出すことを推奨します。例えば 5 秒おきにリモートサーバーへ接続するためにsetInterval() を使用する場合、ネットワークの遅延やサーバーの応答がないなどさまざまな問題で、割り当てられた時間内にリクエストが完了しない可能性があります。そのため、必ずしも順番どおりには返らない XHR リクエストがキュー内にあることに気づくかもしれません。
この場合は、再帰的なsetTimeout() のパターンを推奨します。
(function loop() { setTimeout(() => { // Your logic here loop(); }, delay);})();このコードスニペットでは、名前付き関数loop() を宣言して直ちに実行します。loop() はロジックが完全に実行された後に、内部のsetTimeout() によって再帰呼び出しされます。このパターンは一定の間隔で呼び出すことが保証されませんが、再帰呼び出しの前に前の実行が完了することが保証されます。
仕様書
| Specification |
|---|
| HTML> # dom-setinterval-dev> |