初心者向けのjQuery入門講座|デザイナー向けのJavaScriptライブラリ

このエントリーをはてなブックマークに追加
索引
Core:コアとなる仕組み
Selectors:セレクタ
Attributes:属性
Traversing:対象の変更
Manipulation:操作
CSS:スタイルシート
Events:イベント
Effects:演出効果
Ajax:xml等との連携
Utilities:ユーティリティ
Data:データ
Miscellaneous:諸々
Deferred:処理管理
Callbacks:コールバック
Internals:内部処理

jQuery.when( )promiseオブジェクトの作成

構文

複数の処理を登録しpromiseオブジェクトを作成する返値:promiseオブジェクト
jQuery.when( 処理1,処理2,処理3,… )ver1.5〜
※処理の間に設定する,(カンマ)は忘れやすいので注意してください。

機能

引数で受け取った複数の処理(アニメや通信)をまとめpromiseオブジェクトを作成します。単独で利用することはなくdoneメソッドfailメソッド等と合わせて利用します。

複雑なアニメ演出の管理に便利に利用できそうです。特定のアニメ演出が完了するまではボタンをクリックできなくし、すべての演出が終わったら押せるようにするとか。

解説

まずはwhenメソッドを利用していないサンプルの紹介

サンプル(when/01.html)を開いてbody内にbutton要素とdiv要素があるのを確認してください。jQueryは以下の様に記述され、buttonをクリックしたらdiv要素が2つのアニメを再生するようになっています。このサンプルではまだwhenメソッドは利用していません。

$("button").click(function(){
	$("div").animate({left:300});
	$("div").animate({top:300});
});

buttonをクリックするとdiv要素が右に移動し、その後で下に移動します。

複数のアニメ処理からpromiseオブジェクトを作成する

jQuery.whenメソッドを利用すると、複数の処理からpromiseオブジェクトを作成できます。promiseオブジェクトは処理の管理に便利なメソッドが多く利用でき、アニメの管理に有用だと思います。

サンプル(when/02.html)を開いてbody内の構成はwhen/01.htmlと同じ事を確認してください。jQueryは、まず以下の部分を確認して下さい。2つのアニメ処理をjQuery.whenメソッドの引数に設定し、その返値としてpromiseオブジェクトを得ています(得たpromiseオブジェクトは変数myPromiseに代入しています)。

whenメソッド内の処理は,(カンマ)で区切る必要があります。下のソースでは2行目の最後にあります。忘れないように注意してください。

var myPromise = $.when(
	$("div").animate({left:300}),
	$("div").animate({top:300})
);

以下の処理では、上記の処理で得たmyPromiseにdoneメソッドを利用し、一連の処理が完了したらdiv要素に「DONE!」と表示するようにしました。

myPromise.done(function() {
	$("div").text("DONE!")
});

結果として、buttonをクリックするとアニメが開始され、2つのアニメが完了するとdiv要素に「DONE!」と表示されます。

サンプルwhen/02.htmlでは分かりやすくpromiseオブジェクトを変数myPromiseに代入してい利用しましたが、メソッドチェーンを利用してjQuery.whenメソッドとdoneメソッドを連結することができます。
→参考:サンプル(when/02b.html

$.when(
	$("div").animate({left:300}),
	$("div").animate({top:300})
).done(function() {
	$("div").text("DONE!")
});

通信に利用する

whenメソッドはアニメだけでなくajaxの通信処理もまとめて管理することができます。これを利用すれば「複数の外部データの読込がすべて完了するまで、コンテンツを表示しない」ことが簡単に実現できます。
ちなみにajax通信は画像などの読込には対応していないので、画像の読み込みには利用できません。

サンプル(when/03.html)を開いてbody内の構成を確認してください。コンテンツ(id属性がcontentsのdiv要素)と、ロード画面(id属性がloadのdiv要素)の2つの要素があります。

<div id="load">データの読込中</div>
<div id="contents">コンテンツ</div>

データの読み込みが完了するまでコンテンツは表示したくないので、以下の様に最初はhideメソッドでコンテンツを隠しておきます。

$("#contents").hide();

データの読込はdocumentをクリックすると開始するようにしました。実行する処理は以下の様に記述され、whenメソッドで3つの通信(2〜4行)がまとめられています。そしてすべての通信が完了したら、にdoneメソッドで設定された処理(6〜7行)が実行され、ロード画面をフェードアウトして、コンテンツをフェードインするようにしています。

$.when(
	$.get("../data/simple.xml"),
	$.get("../data/simple.txt"),
	$.get("../data/simple2.txt")
).done(function(){
	$("#load").fadeOut();
	$("#contents").fadeIn();
});

実際にdocumentをクリックすると、3つのデータを読込(小さいファイルなので一瞬で完了すると思います)完了したら、コンテンツ画面がフェードインします。

deferredオブジェクトが追加される以前はajaxStopメソッドを利用していました。
→リファレンス:ajaxStop「すこし実用的なサンプル(全てのデータが揃ってから開始)

メモ

異なった要素のアニメでもOK

解説のサンプルでは1つのdiv要素のアニメを監視しましたが、複数の要素でも可能です。
サンプル(when/test01.html)を開いてbody内に2つのdiv要素があることを確認してください(id属性がaaaとbbb)。jQueryは以下の様に記述されid属性がaaaのdiv要素とbbbのdiv要素のアニメが設定してあります。id属性がbbbのアニメは時間に2000(ミリ秒)を指定しているので、id属性がaaaのアニメよりも時間がかかります。

var myPromise = $.when(
	$("div#aaa").animate({left:300}),
	$("div#aaa").animate({top:300}),
	$("div#aaa").animate({left:0}),
	$("div#bbb").animate({left:300},2000)
);

promiseオブジェクトとしては「すべてのアニメが終了」してからdoneメソッドの内容が実行されるので、追加されたid属性がbbbのdiv要素のアニメも完了してからdoneメソッドの処理が実行されます。

通信の別サンプル

解説の「通信に利用する」ではajaxStopメソッドのサンプルをwhenメソッドで置き換えたサンプルを紹介しましたが、ajaxStartメソッドにもwhenメソッドで置き換えられるサンプルがあるので、ここで紹介しておきます。
→リファレンス:ajaxStop「すこし実用的なサンプル(Now loading)

サンプル(when/test02.html)を開いてbody内にbutton要素とローディングのdiv要素があることを確認して下さい。データを読み込んでいる間だけローディングのdiv要素を表示するようにします。

<button>get</button>
<div>now loading.</div>

最初はローディングのdiv要素を表示しないので、以下の様にhideメソッドで隠しておきます。

$("div").hide();

そしてbuttonをクリックしたら以下の様な処理をするようにしています。サンプルwhen/03.htmlと似ています。

$("div").slideDown();
$.when(
	$.get("../data/simple.xml"),
	$.get("../data/simple.txt"),
	$.get("../data/simple2.txt")
).done(function(){
	$("div").slideUp();
});

まずbuttonがクリックされたら、1行目の処理によってローディングのdiv要素をslideDownメソッドで表示します。そしてwhenメソッドで3つのデータを読込、それが完了したら7行目の処理でローディングのdiv要素をslideUpメソッドで隠します。

結果として、buttonをクリックするとデータを読み込む間だけローディングが表示されます(読み込むデータが小さいので短い時間ですが)。

deferredオブジェクトが追加される以前はajaxStartメソッドやajaxStopメソッドを利用していました。
→リファレンス:ajaxStop「すこし実用的なサンプル(Now loading)