.setTimeout()
指定した遅延時間の後に、関数の呼び出し、またはコードの実行を行います。
文法
//関数指定
var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);
//コード指定
var timeoutID = window.setTimeout(code, delay);
timeoutID
は一意のタイムアウトのIDで、
これはwindow.clearTimeout()に渡すことが出来ます。
引数 | 説明 |
---|---|
func |
(関数指定の場合)delay ミリ秒後に実行したい関数(function)を指定します。
|
code |
(コード指定の場合) 関数指定の代わりとなる文法で、 delay ミリ秒後に実行したいコード文字列を指定します。
(この構文の使用は、eval()の使用と同じ理由で推奨されません。)
|
delay | 遅延させる時間をミリ秒(1/1000)単位の数値で指定します。 実際の遅延は少しだけ長くなるでしょう。 詳細は後述する「注意事項」を参照してください。 |
1つ目の文法で関数へ引数(param1, param2
)を渡すことは、
Internet Explorer 9とそれ以前のバージョンで動作しません。
もしこの機能を有効にしたいのであれば、互換性のあるコードを使用しなければいけません。
(詳細は、「コールバック引数」の段落を参照してください。)
重要: Gecko 13 (Firefox 13.0 / Thunderbird 13.0 / SeaMonkey 2.10)より前のバージョンでは、 Geckoは追加の引数として、コールバックの"実際の遅延時間"(ミリ秒)を渡していました。 この非標準の引数は、現在は渡されません。
例
下記の例は2つのシンプルなボタンをWebページ上に配置し、
setTimeoutとclearTimeoutのそれぞれの処理を実行します。
1つ目のボタンが押されると、
2秒後に警告(alert)ダイアログを呼び出すタイムアウトが設定され、
timeoutID
にclearTimeoutで使用されるIDが格納されます。
2つ目のボタンを押すことで、
任意にこのタイムアウト処理をキャンセルすることが出来ます。
<!DOCTYPE html>
<html>
<head>
<title>setTimeoutデモ</title>
</head>
<body>
<p>ライブデモ</p>
<button id="delayed_btn">2秒後に警告(alert)ダイアログを表示</button>
<p></p>
<button id="clear_btn">警告ダイアログをキャンセル</button>
<script>
var timeoutID;
function delayedAlert() {
timeoutID = window.setTimeout(slowAlert, 2000);
}
function slowAlert() {
alert("遅延して表示しています!");
}
function clearAlert() {
window.clearTimeout(timeoutID);
}
var delayed_btn = document.getElementById('delayed_btn')
var clear_btn = document.getElementById('clear_btn')
delayed_btn.onclick = delayedAlert;
clear_btn.onclick = clearAlert;
</script>
</body>
</html>
clearTimeoutの例も、 参照してください。
コールバック引数
コールバック関数に引数を渡す必要があり、
更に追加の引数(setTimeout()
、setInterval()のどちらも)が、
サポートされないInternet Explorer 9以下でも動作する必要がある場合、IE仕様に互換性のあるコードを含める必要があります。
下記のスクリプトは、単にスクリプトの先頭に挿入して、
両方のタイマーでそのブラウザでのHTML5の標準的な引数渡しの機能を有効にします。
/*\
|*|
|*| JavaScriptのタイマーへのコールバック関数に
|*| 任意の引数を渡すことを有効にするIE用のPolyfillです。
|*| (HTML5標準文法)
|*|
|*| https://developer.mozilla.org/en-US/docs/DOM/window.setInterval
|*|
|*| 文法:
|*| var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);
|*| var timeoutID = window.setTimeout(code, delay);
|*| var intervalID = window.setInterval(func, delay[, param1, param2, ...]);
|*| var intervalID = window.setInterval(code, delay);
|*|
\*/
if (document.all && !window.setTimeout.isPolyfill) {
var __nativeST__ = window.setTimeout;
window.setTimeout = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
var aArgs = Array.prototype.slice.call(arguments, 2);
return __nativeST__(vCallback instanceof Function ? function () {
vCallback.apply(null, aArgs);
} : vCallback, nDelay);
};
window.setTimeout.isPolyfill = true;
}
if (document.all && !window.setInterval.isPolyfill) {
var __nativeSI__ = window.setInterval;
window.setInterval = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
var aArgs = Array.prototype.slice.call(arguments, 2);
return __nativeSI__(vCallback instanceof Function ? function () {
vCallback.apply(null, aArgs);
} : vCallback, nDelay);
};
window.setInterval.isPolyfill = true;
}
IEのみの修正
もし、IE9以下を含む各モバイルとデスクトップブラウザを控えめにハックしたいのであれば、 JavaScriptの条件付きのコメントを使用することも可能です。
/*@cc_on
// conditional IE < 9 only fix
@if (@_jscript_version <= 6)
(function(f){
window.setTimeout =f(window.setTimeout);
window.setInterval =f(window.setInterval);
})(function(f){return function(c,t){var a=[].slice.call(arguments,2);return f(function(){c.apply(this,a)},t)}});
@end
@*/
または、IEのHTML条件機能をベースにした、すっきりした書き方もあります。
<!--[if lte IE 9]><script>
(function(f){
window.setTimeout =f(window.setTimeout);
window.setInterval =f(window.setInterval);
})(function(f){return function(c,t){
var a=[].slice.call(arguments,2);return f(function(){c.apply(this,a)},t)}
});
</script><![endif]-->
別の解決法に、コールバック関数の呼び出しに無名関数を使用する方法がありますが、 これは少し手間が掛かります(冗長です)。例えば、下記のように指定します。
var intervalID = setTimeout(function() { myFunc("one", "two", "three"); }, 1000);
更に別の方法に、関数のbindを使用する方法があります。 例えば、下記のように指定します。
setTimeout(function(arg1){}.bind(undefined, 10));
this問題
setTimeout()にメソッドを渡した場合(または、他の関数)、 異なるthis値で実行されます。 この事については、thisのページに詳細が説明されています。
解説
setTimeout()
によって実行されるコードは、
それが呼び出された関数とは別のコンテキスト内で実行されます。
そのため、呼び出された関数のthis
キーワードには、
window(またはグローバル)オブジェクトが設定され、
setTimeoutを呼び出した関数のthis
値とは異なります。
下記の例を参考にしてください。
myArray = ["zero", "one", "two"];
myArray.myMethod = function (sProperty) {
//引数があれば this[sProperty] の値を
//引数が無ければ this 値を出力
alert(arguments.length > 0 ? this[sProperty] : this);
};
// "zero,one,two"を出力
myArray.myMethod();
// "one"を出力
myArray.myMethod(1);
// 1秒後に"[object Window]"を出力
setTimeout(myArray.myMethod, 1000);
// 1.5秒後に"undefined"を出力
setTimeout(myArray.myMethod, 1500, "1");
// 'this'オブジェクト渡しを試してみましょう。
// error: "NS_ERROR_XPC_BAD_OP_ON_WN_PROTO:
//Illegal operation on WrappedNative prototype object"
setTimeout.call(myArray, myArray.myMethod, 2000);
// 下記も同じエラーになります。
setTimeout.call(myArray, myArray.myMethod, 2500, 2);
ご覧の通り、コールバック関数へthis
オブジェクトを渡すことは出来ません。
解決策
"this"問題の解決可能な方法は、2つのネイティブなグローバル関数である、
setTimeout()とsetInterval()を、
Function.prototype.callを通して、
this
渡しが可能な非ネイティブな関数に置き換えることです。
下記はその置き換えの方法になります。
// JavaScriptのタイマー関数への'this'オブジェクト渡しを有効にします
var __nativeST__ = window.setTimeout, __nativeSI__ = window.setInterval;
window.setTimeout = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
var oThis = this, aArgs = Array.prototype.slice.call(arguments, 2);
return __nativeST__(vCallback instanceof Function ? function () {
vCallback.apply(oThis, aArgs);
} : vCallback, nDelay);
};
window.setInterval = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
var oThis = this, aArgs = Array.prototype.slice.call(arguments, 2);
return __nativeSI__(vCallback instanceof Function ? function () {
vCallback.apply(oThis, aArgs);
} : vCallback, nDelay);
};
注意: この2つの置換は、IEにおいてのHTML5標準のコールバック関数への任意の引数渡しも有効です。 そのため、Polyfillとして使用することも出来ます。 「コールバック引数」の段落を参照してください。
新しい機能の検証:
myArray = ["zero", "one", "two"];
myArray.myMethod = function (sProperty) {
alert(arguments.length > 0 ? this[sProperty] : this);
};
// setTimeoutとsetIntervalの標準的な使用方法を保護しつつ…
setTimeout(alert, 1500, "Hello world!");
// 2秒後に、"zero,one,two"を出力
setTimeout.call(myArray, myArray.myMethod, 2000);
// 2.5秒後に"two"を出力
setTimeout.call(myArray, myArray.myMethod, 2500, 2);
"this"問題のみを、ネイティブで解決する方法は存在しません。
注意: JavaScript 1.8.5では、Function.prototype.bind()メソッドが導入され、
このメソッドは与えられた関数内での、全ての呼び出しで使用されるthis
値を開発者に指定させます。
これは、this
値が呼び出される関数のコンテキストによって、
何になるのかはっきりしない問題を解決する手助けになってくれます。
注意事項
window.clearTimeout()を使用して、タイムアウトをキャンセルすることが出来ます。 もし、関数呼び出しを繰り返し(例えば、Nミリ秒毎に)行いたい場合は、 window.setInterval()の使用を検討してください。
setTimeout()を呼び出したスレッドが終了するまで、関数またはコードは実行出来ないということを、 覚えておかなければいけません。これは非常に重要な事です。
文字列リテラル渡しについて
setTimeout()へ関数を渡す代わりに文字列を渡すことは、 evalの使用と同様に危険が伴います。
// 適切
window.setTimeout(function() {
alert("Hello World!");
}, 500);
// 不適切
window.setTimeout("alert(\"Hello World!\");", 500);
文字列リテラルはグローバルコンテキスト内で評価されるため、 コードとして文字列を評価した場合、呼び出されたsetTimeout()コンテキスト内のローカルシンボルは、 利用することが出来ません。
遅延の最小/最大値とタイムアウトの入れ子について
歴史的に、
ブラウザはsetTimeout()に対して制限をかけてきました。
遅延して連続で呼び出されるsetTimeout()が、"最小遅延時間"制限よりも小さい場合は、
最小遅延時間が強制的に使用されます。
最小遅延時間であるDOM_MIN_TIMEOUT_VALUE
は4ミリ秒(Firefoxの設定のdom.min_timeout_value
)で、
DOM_CLAMP_TIMEOUT_NESTING_LEVEL
は5ミリ秒です。
実際、4ミリ秒はHTML5仕様であり、 2010年以降にリリースされたブラウザ間で一貫したものになっています。 以前(Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2)は、 この最小のタイムアウト値は10ミリ秒でした。
この"制限"に加え、この遅延時間はページ(またはOS/ブラウザ自身)の別の処理状況によって、 発火されるのが更に遅れる事もあります。
モダンブラウザで0ミリ秒のタイムアウトを実装するには、 window.postMessage()を使用して、 ここで説明されているようにします。
Internet Explorer、Chrome、Safari、Firefoxを含むブラウザは、
内部に32ビットの符号付き整数として遅延時間を格納します。
これは、2147483647
より大きい遅延時間を使用した場合、
整数のオーバーフローを引き起こし、結果的に即座にタイムアウトが実行されることになります。
非アクティブなタブについて
(Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2)とChrome11では、 非アクティブなタブでは、タイムアウトの実行が1秒間(1000ミリ秒)に一度だけに制限されます。 この事に関するより詳細な情報については、 Mozillaはbug 633421を、 Chromeはcrbug.com/66078を参照してください。
ブラウザ互換性
機能 | Chrome | Firefox (Gecko) |
IE | Opera | Safari |
---|---|---|---|---|---|
基本 | 1.0 | 1.0 (1.7 or earlier) | 4.0 | 4.0 | 1.0 |
callback(*1) 引数をサポート |
◯ | ◯ | 10.0 | ◯ | ? |
機能 | Android | Chrome for Android |
Firefox Mobile |
IE Mobile |
Opera Mobile |
Safari Mobile |
---|---|---|---|---|---|---|
基本 | 1.0 | 1.0 | 1.0 (1) | 6.0 | 6.0 | 1.0 |
callback(*1) 引数をサポート |
? | ? | ? | ? | ? | ? |
*1 関数を使用する文法で、任意の引数をサポートするか否かです。
仕様
HTML5で仕様となったDOMレベル0の一部です。
関連項目
© 2017 Mozilla Contributors
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
このページは、ページトップのURL先のMozilla Developer Network(以下、MDN)のコンテンツを翻訳した内容を基に構成されています。 構成について異なる点も含まれますので、下記の項目を確認し、必要に応じて元のコンテンツをご確認ください。 もし、誤訳などの間違いを見つけましたら、 @tomofまで教えていただければ幸いです。
- 特定のブラウザに特化しすぎている情報やあまりにも古い情報、 または試験的に導入されているようなAPIや機能については、省略していることがあります。
- 例やデモについて、実際にページ内で動作させる関係で一部ソースコードを変更している場合や、 その例で使用しているコンテンツの単語や文章などを日本人向けに変更しいてる場合があります。
- MDNの更新頻度が高いため、元のコンテンツと比べ情報が古くなっている可能性があります。
- "訳注:"などの断わりを入れた上で、日本人向けの情報の追記を行っている事があります。