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

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

.promise( )要素からpromiseオブジェクトを作成

構文

要素からpromiseオブジェクトを作成返値:promiseオブジェクト
jQo.promise( [キュー名] [, ターゲット名] )ver1.6〜

機能

jQueryオブジェクトで指定した要素からpromiseオブジェクトを作成します。引数の「タイプ」を設定すると監視するアニメのキューを指定できます(デフォルトはfxです)。引数の「ターゲット名」を設定すると、promiseオブジェクトを、そのターゲットに設定できます。

作成されたpromiseオブジェクトは要素のデータとして保存されるので、処理の途中でremoveメソッドで要素を削除すると処理が完了しないままになってしまいます。もし処理の途中で要素を削除する必要がある場合は要素のデータを保持するdetachメソッドを利用してください。

解説

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

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

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

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

要素からpromiseオブジェクトを作成する

promiseメソッドはアニメが設定された要素(jQueryオブジェクト)からpromiseオブジェクトを作成できます。
サンプル(promise/02.html)を開いてbody内の構成はpromise/01.htmlと同じ事を確認してください。

jQueryは、まず以下の部分を確認して下さい。2つのアニメを設定しているところまではpromise/01.htmlと同じですが、3行目でpromiseメソッドを利用してアニメが設定されたdiv要素からpromiseオブジェクトを作成しています。作成したpromiseオブジェクトは変数「myPromise」に代入しています。

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

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

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

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

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

$("button").click(function(){
	$("div").animate({left:300});
	$("div").animate({top:300});
	$("div").promise().done(function() {
		$("div").text("DONE!")
	});
});

buttonをクリックするとpromise/02.htmlと同じように正常に機能します。

ターゲット名を指定する

引数にターゲット名を指定すると、すでに存在するobjectオブジェクトなどにpromiseオブジェクトを設定できます。サンプル(promise/03.html)を開いてbody内の構成はpromise/02.htmlと同じ事を確認してください。

jQueryもpromise/02.htmlと似ていますが、以下の様にobjectオブジェクト「myPromise」が作成され、これをpromiseメソッドの第2引数に設定しています。第1引数の「fx」はデフォルトのキュー名です。

$("div").animate({left:300});
$("div").animate({top:300});
myPromise = new Object();
$("div").promise("fx", myPromise);

この構文でもmyPromiseがpromiseオブジェクトになるため、promise/02.htmlと同様にアニメが完了したら「DONE!」と表示されます。すでに存在しているオブジェクトをpromiseオブジェクトとしたい時に利用する構文なのだと思います(たぶん)。

メモ

複数の要素に対応しています

whenメソッドでは複数の要素のアニメをまとめて管理することができました(参考:異なった要素のアニメでもOK)が、promiseメソッドでも同じように複数の要素のアニメをまとめて管理することができます。

サンプル(promise/test01.html)を開いてbody内にbutton要素と2つのdiv要素(id属性はaaaとbbb)があることを確認してください。この2つのdiv要素のアニメをまとめて管理します。

<button>click</button>
<div id="aaa"></div>
<div id="bbb"></div>

jQueryではbuttonをクリックすると以下の処理を実行するようにしています。まず1〜4行目で2つのdiv要素にアニメ(id属性aaaには3つ、bbbには1つ)を設定しています。

$("div#aaa").animate({left:300});
$("div#aaa").animate({top:300});
$("div#aaa").animate({left:0});
$("div#bbb").animate({left:300},2000);
$("div").promise().done(function() {
	$("div").text("DONE!")
});

そしてポイントは5行目です。promiseメソッドのセレクタにはdivが指定してあるため、id属性aaaとbbbの2つの要素のアニメをまとめて管理することになります。

作成したpromiseオブジェクトはメソッドチェーンでdoneメソッドを連結し、アニメが完了したらdiv要素に「DONE!」と表示するようにしました。

実際にbuttonをクリックすると、2つのアニメが両方とも完了してから「DONE!」と表示されます。この結果から、promiseメソッドでも複数の要素のアニメを管理できることが確認できます。

通信には利用できません

ajax通信をするメソッドはpromiseオブジェクトを含んだjqXHRオブジェクトを返すため、promiseメソッドは必要ありません。しかし通信系で唯一jqXHRオブジェクトを返さないloadメソッドというのがあるので、これからpromiseオブジェクトを作成できるか試してみました。できた所でメリットもないと思うのですが興味本位で..。

サンプル(promise/test02.html)を開いてbody内にbutton要素とdiv要素が1つずつあることを確認してください。jQueryではbuttonをクリックしたら、以下の処理をするようにしました。

$("div").load("../data/simple.txt").promise().done(function(){
	alert("DONE!")
});

まずloadメソッドで外部データの「simple.txt」を読込、div要素に表示します。そしてメソッドチェーンでpromiseメソッドを連結しpromiseオブジェクトを作成し、それをdoneメソッドに渡し、完了したらアラートで「DONE!」と表示するようにしました。

実際にbuttonをクリックすると、div要素にデータが表示されてアラートで「DONE!」と表示されました。しかし何となく不安だったので、読込に失敗するサンプルでも確認するようにしました。

サンプル(promise/test02b.html)を開いてbody内の構成がtest02.htmlと同じ事を確認してください。jQueryは以下の様に読込データを存在しない「no.txt」に変更しています。

$("div").load("../data/no.txt").promise().done(function(){
	alert("DONE!")
});

このサンプルでbuttonをクリックすると、ファイルが無いため読込に失敗してdiv要素には何も表示されないのですが、doneメソッドによるアラートで「DONE!」と表示されます。

promiseオブジェクトに対するdoneメソッド失敗した時には実行されないので、これは正常なpromiseオブジェクトが作成できていないことを意味します。やはり通信系のloadメソッドからはpromiseオブジェクトを作成する事はできませんでした。引数に「キュー」の設定があることからもアニメ専用のメソッドなのでしょう
繰り返しになりますが、loadメソッド以外の通信系メソッドはpromiseオブジェクトを内包したjqXHRオブジェクトを返すので、そもそもpromiseメソッドは必要ありません。