6/4追記
追記しました。返り値として渡すべきものが何か分かっていなかった点が問題でした。
$.DeferredはjQuery1.5より実装された非同期処理を扱うためのオブジェクトです。
$.Deferredについての解説記事やサンプルコードは検索すれば多く見つかりますが、大抵Ajaxの非同期処理での利用方法となっています。
ですが$.DeferredはAjaxでなくても、アニメーションなどの処理を連鎖的に実行する際にも利用することができます。
実務的にはAjaxよりも連鎖的な処理として利用するほうが頻度が高いと思いますので、参考にしてみてください。
ADs
まず順次実行したい処理を返り値をfunctionとする関数として定義します(以下の例のfunc01,func02…がそれにあたる)。
言葉で書くと難しいように見えますが、普段jQueryを使って書いているメソッドの頭にreturnをつけるだけです。
そして実行したい順番にthen()でつなぎ、最後にresolve()で実行します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
(function($){ //functionを返り値として取る関数を定義する var func01 = function(){ return 行いたい処理; } var func02 = function(){ return 行いたい処理; } var func03 = function(){ return 行いたい処理; } ..... $(function(){ //$.Defferred!! var def = $.Deferred(function(d){ //func01が終わったらfunc02,終わったらfunc03...と順番に実行される d.then(func01),then(func02).,then(func03).....; }); def.resolve();//resolve()で実行される }); })(jQuery); |
1 2 3 4 5 6 7 8 |
var test = function(){ var d = new $.Deferred(); setTimeout(function(){ //なんか処理 d.resolve(); }, 1000); return d.promise(); } |
アニメーション関連の処理の場合はjQuery1.8より返り値としてpromiseオブジェクトを返すようになりましたので、結果的にpromimseオブジェクトを返しています。
$.Deferredの部分は実行したい順番につなぐだけなので、特に難しい点はないと思います。
関数定義の部分をいくつか具体的に書いてみました。
最も簡単な例ですが、単純なアニメーションの場合は頭にreturnをつけるだけです。
アニメーションの場合は完了後に処理をつないでいこうとするとコールバックまみれになってしまいますが、then()でつなぐことで書きやすく読みやすいコードとなります。
1 2 3 |
var anim0 = function(){ return $('.block').fadeIn('slow'); } |
同様に以下のようなスタイルを定義する処理も書くことができます。
アニメーションが終わったら背景色を変更して、次のアニメーションを実行する、というような連続した処理が可能となります。
1 2 3 |
var anim0 = function(){ return $('.item').css('background-color','#00f'); } |
1 2 3 |
var anim0 = function(){ $('.item').css('background-color','#00f'); } |
でよかったです。
ループを使った処理は場合によっては時間がかかり、ループが完了しないうちに次の処理が走ってしまうことがありますが、そういった事態を避けることができます。
以下のようにdelayを使った場合でも、きちんとループ終了後に次の処理に移ることができます。
1 2 3 4 5 |
var anim1 = function(){ return $('.item').each(function(key,value){ $(this).delay(key*100).fadeIn(); }); }; |
上記functionはeach()の完了を待っていたわけではなく、すべてのfadeIn()の完了を待っていた、ということです。
ここまでは1行で書ける処理ばかりでしたが、1行で書けない、つまり複数のオブジェクトに対する処理を同時に実行させる場合は以下のように一つの関数にまとめます。
ただのfunctionでは実行されませんので、即時関数にして実行されるようにします。
1 2 3 4 5 6 |
var anim3 = function(){ return (function(){ $('.item').css('background-color','#00f'); $('.block').css('background-color','#333'); })(); }; |
1 2 3 4 |
var anim3 = function(){ $('.item').css('background-color','#00f'); $('.block').css('background-color','#333'); }; |
で問題ありません。
ソースを見れば分かりやすいですが、
1.div.blockをフェードイン
2.div.itemを0.1秒おきに1個ずつフェードイン
3.div.itemを0.1秒おきに1個ずつフェードアウト
4.div.itemを0.1秒おきに1個ずつフェードイン
5.div.itemの背景を#00fに、div.blockの背景を#333に
6.div.itemを0.1秒おきに1個ずつフェードアウト
7.div.blockに「おつかれ!」という文字列をappned()
という処理を順番に行なっています。
$.Deferredを使わなければ7階層のコールバック地獄になっているかもしれませんが、極めてシンプルに記述することができます。
ADs
コメントはまだありません。