JavaScript プログラミング講座

 

一定時間経過後に、任意の関数を実行する

 


■一定時間経過後に、任意の関数を実行する

 
setTimeout() メソッドを使用します。
 
コールバック関数は、一定時間経過後に1回だけ実行されます。
 
このメソッドは、非同期実行です。
 
すぐに制御が返り、プログラムは動き続けます。
 
中止したい場合は、clearTimeout() メソッドを使用します。
 
Window.setTimeout( 関数 , 時間 , データ ... ) :Number
第01引数 Function実行したいコールバック関数を指定。
第02引数 Numberコールバック関数を実行するまでに待機する時間を指定(単位:ミリ秒)
可変引数(略可)*コールバック関数の引数に、任意のデータを渡したい場合に指定。(一部のブラウザのみ対応)
戻り値 Numberハンドル値が得られる。clearTimeout() メソッドで使用する。
 
■第01引数 セキュリティリスクについて
 
eval() 関数と同じ危険性があります。
 
文字列を指定すると、JavaScript として評価され、実行されます。
 
外部から得られる不定の文字列を、第01引数に渡してはいけません。
 
外部から悪意のあるスクリプトを実行する事ができるため危険です
 
第01引数に文字列を指定すると JavaScript として評価実行されるので危険

// ------------------------------------------------------------
// 適当な文字列
// ------------------------------------------------------------
var str = 'alert("実行された");';

// ------------------------------------------------------------
// × JavaScript として評価実行されるので危険
// ------------------------------------------------------------
setTimeout(str , 1000);
 
■第02引数(待機する時間)
 
コールバック関数が実行されるまでに、待機する時間をミリ秒で指定します。
 
必ずしも、指定した時間経過後に実行されるとは限りません。
 
一部のブラウザでは、ページが隠れている場合、最短でも約 1000ミリ秒後に実行されます。
 
ページの可視性については、こちらで解説しています。
 
また、HTML5 の仕様では、最短の時間は 4 ミリ秒と勧告されています。
 
■使用例
 
5000 ミリ秒経過後に,関数を実行する

// ------------------------------------------------------------
// 一定時間経過後に実行される関数
// ------------------------------------------------------------
function TimeoutFunc(){
	alert("実行された");
}

// ------------------------------------------------------------
// 5000 ミリ秒経過後に、関数を実行する
// ------------------------------------------------------------
var timeout_id = setTimeout(TimeoutFunc , 5000);
 
第03引数の動作を確認する(一部のブラウザのみ対応)

// ------------------------------------------------------------
// 一定時間経過後に実行される関数
// ------------------------------------------------------------
function TimeoutFunc(argument1,argument2,argument3){

	// 出力テスト
	console.log(argument1); // false
	console.log(argument2); // 123
	console.log(argument3); // "あいう"
	console.log(arguments);
}

// ------------------------------------------------------------
// 1000 ミリ秒経過後に、関数を実行する
// ------------------------------------------------------------
var timeout_id = setTimeout(TimeoutFunc , 1000 , false , 123 , "あいう");
 

■ setTimeout() メソッドの動作をキャンセルする

 
clearTimeout() メソッドを使用します。
 
setTimeout() メソッドで生成された依頼を破棄します。
 
Window.clearTimeout( ハンドル値 ) :Void
第01引数 NumbersetTimeout() メソッドで得られたハンドル値を指定。
戻り値 Voidなし。
 
setTimeout() メソッドのタイマー動作をキャンセルする

// ------------------------------------------------------------
// 変数
// ------------------------------------------------------------
var timeout_id = null;

// ------------------------------------------------------------
// 5000 ミリ秒経過後に、関数を実行する
// ------------------------------------------------------------
timeout_id = setTimeout(function (){

	alert("実行された");

} , 5000);

// ------------------------------------------------------------
// タイマーを停止する
// ------------------------------------------------------------
if(timeout_id !== null){

	// setTimeout() メソッドの動作をキャンセルする
	clearTimeout(timeout_id);

	timeout_id = null;
}
 

■一定の時間隔で繰り返しコールバック関数を実行する

 
コールバック関数内で、もう一度 setTimeout() メソッドを利用します。
 
すると、一定の時間隔で繰り返しコールバック関数を実行する事ができます。
 
setTimeout() メソッドを使って、一定時間隔で任意の関数を実行する

// ------------------------------------------------------------
// TimerInterval コンストラクタ関数
// ------------------------------------------------------------
function TimerInterval(callback,delay){

	var _timeout_id = null;

	// ------------------------------------------------------------
	// タイマーを停止
	// ------------------------------------------------------------
	this.stop = function (){
		if(_timeout_id !== null){
			clearTimeout(_timeout_id);
			_timeout_id = null;
		}
	};

	// ------------------------------------------------------------
	// 初期化
	// ------------------------------------------------------------
	_timeout_id = setTimeout(function callee(){
		callback();
		if(_timeout_id === null) return;
		_timeout_id = setTimeout(callee,delay);
	},delay);
}


// ------------------------------------------------------------
// 1000 ミリ秒の時間隔で繰り返し実行
// ------------------------------------------------------------
var timer = new TimerInterval(function (){

	console.log("実行された");

} , 1000);

// ------------------------------------------------------------
// 繰り返し実行を終了
// ------------------------------------------------------------
//timer.stop();
 

■setInterval() と setTimeout() の繰り返し実行の違い

 
■setInterval() による繰り返し実行について
 
関数の実行を開始した時点から、次のタイムカウントを開始します。
 
 
■setTimeout() による繰り返し実行について
 
例えば、コールバック関数の開始直後に、setTimeout() メソッドを利用します。
 
この場合、関数の実行を開始した時点から、次のタイムカウントを開始します。
 
例えば、コールバック関数の終了直前に、setTimeout() メソッドを利用します。
 
この場合、実行が終了した時点から、次のタイムカウントを開始します。
 
 
■遅延発生時のメモリリークについて
 
遅延すると、キューが無制限に溜まってしまうという事はありません。
 


 

一定の時間間隔で、任意の関数を実行する

 


■一定の時間間隔で、任意の関数を実行する


setInterval() メソッドを使用します。
 
コールバック関数は、一定の時間間隔で繰り返し実行されます。
 
このメソッドは、非同期実行です。
 
すぐに制御が返り、プログラムは動き続けます。
 
中止したい場合は、clearInterval() メソッドを使用します。
 
Window.setInterval( 関数 , 時間隔 , データ ... ) :Number
第01引数 Function実行したいコールバック関数を指定。
第02引数 Number関数を繰り返し実行するための時間隔を指定(1 以上の数値)(単位:ミリ秒)
可変引数(略可)*コールバック関数の引数に、任意のデータを渡したい場合に指定。(一部のブラウザのみ対応)
戻り値 Numberハンドル値が得られる。clearInterval() メソッドで使用する。
 
■第01引数 セキュリティリスクについて
 
eval() 関数と同じ危険性があります。
 
文字列を指定すると、JavaScript として評価され、実行されます。
 
外部から得られる不定の文字列を、第01引数に渡してはいけません。
 
外部から悪意のあるスクリプトを実行する事ができるため危険です
 
第01引数に文字列を指定すると JavaScript として評価実行されるので危険

// ------------------------------------------------------------
// 適当な文字列
// ------------------------------------------------------------
var str = 'alert("実行された");';

// ------------------------------------------------------------
// × JavaScript として評価実行されるので危険
// ------------------------------------------------------------
setInterval(str , 5000);
 
■第02引数(時間隔)
 
コールバック関数を繰り返し実行する、時間隔をミリ秒で指定します。
 
最低でも 1 以上の数値を指定します。
 
Internet Explorer の場合、0 を指定すると、関数が 1 度だけしか実行されません。
 
■実行タイミングについて
 
必ずしも、指定した時間間隔で実行されるとは限りません。
 
一部のブラウザでは、ページが隠れている場合、約 1 ~ 8 fps まで低下します。
 
ページの可視性については、こちらで解説しています。
 
また、HTML5 の仕様では、最短の時間は 4 ミリ秒と勧告されています。
 
■使用例
 
5000 ミリ秒の時間隔で関数を実行する

// ------------------------------------------------------------
// 一定時間隔で、繰り返し実行される関数
// ------------------------------------------------------------
function IntervalFunc(){
	alert("実行された");
}

// ------------------------------------------------------------
// 5000 ミリ秒の時間隔で関数を実行する
// ------------------------------------------------------------
var interval_id = setInterval(IntervalFunc , 5000);
 
第03引数の動作を確認する(一部のブラウザのみ対応)

// ------------------------------------------------------------
// 一定時間経過後に実行される関数
// ------------------------------------------------------------
function IntervalFunc(argument1,argument2,argument3){

	// 出力テスト
	console.log(argument1); // false
	console.log(argument2); // 123
	console.log(argument3); // "あいう"
	console.log(arguments);
}

// ------------------------------------------------------------
// 1000 ミリ秒の時間隔で関数を実行する
// ------------------------------------------------------------
var interval_id = setInterval(IntervalFunc , 1000 , false , 123 , "あいう");
 

■ setInterval() メソッドの動作をキャンセルする

 
clearInterval() メソッドを使用します。
 
setInterval() メソッドで生成された依頼を破棄します。
 
Window.clearInterval( ハンドル値 ) :Void
第01引数 NumbersetInterval() メソッドで得られたハンドル値を指定。
戻り値 Voidなし。
 
setInterval() メソッドのタイマー動作をキャンセルする

// ------------------------------------------------------------
// 変数
// ------------------------------------------------------------
var interval_id = null;

// ------------------------------------------------------------
// 5000 ミリ秒の時間隔で関数を実行する
// ------------------------------------------------------------
interval_id = setInterval(function (){

	alert("実行された");

} , 5000);

// ------------------------------------------------------------
// タイマーを停止する
// ------------------------------------------------------------
if(interval_id !== null){

	// setInterval() メソッドの動作をキャンセルする
	clearInterval(interval_id);

	interval_id = null;
}
 


 

アニメーション更新時に、任意の関数を実行する(HTML5 世代)

 
 


■アニメーションフレームについて


HTML5 世代の機能です。
 
http://www.w3.org/TR/animation-timing/
 
■ブラウザのアニメーション更新について
 
約 60fps (1000/60ミリ秒) の時間隔で発生します。
 
■リクエストについて
 
ブラウザの再描画タイミングに合わせて、任意の描画用関数を実行する事ができます。
 
この機能を使って、ティアリングを防止する事はできないようです。
 

■アニメーションフレームに対応しているか調べる


window.requestAnimationFrame プロパティを調べます。
 
結果が真であれば、利用可能です。
 
Opera(Presto 版) では、未対応です。
 
Internet Explorer 9 以前では、未対応です。
 
アニメーションフレームに対応しているか調べる

// アニメーションフレームに対応している
if(window.requestAnimationFrame){

	alert("対応している");

}else{

	alert("対応していない");

}
 
 

■アニメーション更新時に、任意の関数を実行する


requestAnimationFrame() メソッドを使用します。
 
コールバック関数は、次回のアニメーション更新時に1回だけ実行されます。
 
このメソッドは、非同期実行です。
 
すぐに制御が返り、プログラムは動き続けます。
 
中止したい場合は、cancelAnimationFrame() メソッドを使用します。
 
Window.requestAnimationFrame ( 関数 ) :Number
第01引数 Function実行したいコールバック関数を指定。
戻り値 Numberハンドル値が得られる。(0 以外の識別値)
 
■実行タイミングについて
 
アニメーション更新は、必ずしも約 60fps (1000/60ミリ秒) を維持するとは限りません。
 
ページが隠れた状態である場合、レートが、約 0 ~ 1 fps まで低下します。
 
ページの可視性については、こちらで解説しています。
 
■コールバック関数の引数について
 
コールバック関数の第01引数から、高分解能タイマーが得られます。
 
得られる単位はミリ秒です。(分解能はマイクロ秒)
 
この値を参考にして、遅延の発生を検出する事ができます。
 
前回とタイマー値が一致する場合、同一の更新タイミングを意味します。
 
この場合、最新の描画処理を省略するのもいいでしょう。
 
一部のブラウザでは、フレームスキップ発生時にも、前回とタイマー値が一致します。
 
■使用例
 
次のアニメーション更新発生時に、関数を実行する

// ------------------------------------------------------------
// 次のアニメーション更新発生時に実行される関数
// ------------------------------------------------------------
function AnimationFrameFunc(time){
	console.log("描画:" + time);
}

// ------------------------------------------------------------
// 次のアニメーション更新発生時に、関数を実行する
// ------------------------------------------------------------
var anime_frame_id = window.requestAnimationFrame(AnimationFrameFunc);
 
実行ループ内から描画リクエストを発行する

// ------------------------------------------------------------
// 変数
// ------------------------------------------------------------
var time_old = 0;
var anime_frame_id = null;

// ------------------------------------------------------------
// 次のアニメーション更新発生時に実行される関数
// ------------------------------------------------------------
function AnimationFrameFunc(time){
	// 同一タイミングの二度実行を回避
	if(time_old == time) return;

	// --- 描画処理開始 ---
	console.log("描画:" + time);
	// --- 描画処理終了 ---

	// タイマー情報を残す
	time_old = time;
}

// ------------------------------------------------------------
// 120 FPS の時間隔で関数を実行する
// ------------------------------------------------------------
setInterval(function()){

	// --- 実行処理開始 ---
	console.log("実行");
	// --- 実行処理終了 ---

	// 次のアニメーション更新発生時に、描画関数を実行する
	anime_frame_id = window.requestAnimationFrame(AnimationFrameFunc);

},1000/120);

 

■ requestAnimationFrame() メソッドの動作をキャンセルする

 
cancelAnimationFrame() メソッドを使用します。
 
requestAnimationFrame() メソッドで生成された依頼を破棄します。
 
Window.cancelAnimationFrame( ハンドル値 ) :Void
第01引数 NumberrequestAnimationFrame() メソッドで得られたハンドル値を指定。
戻り値 Voidなし。
 
requestAnimationFrame() メソッドのタイマー動作をキャンセルする

// ------------------------------------------------------------
// 変数
// ------------------------------------------------------------
var anime_frame_id = null;

// ------------------------------------------------------------
// 次のアニメーション更新発生時に、関数を実行する
// ------------------------------------------------------------
anime_frame_id = requestAnimationFrame(function (time){

	alert("描画:" + time);

});

// ------------------------------------------------------------
// タイマーを停止する
// ------------------------------------------------------------
if(anime_frame_id){

	// requestAnimationFrame() メソッドの動作をキャンセルする
	cancelAnimationFrame(anime_frame_id);

	anime_frame_id = null;
}