2009-10-20 17 views
19

多くの場合、アニメーションを同期して実行します。特に、私は一連の連続したアニメーションを作りたいと思っています。JQuery同期アニメーション

jQuery animate関数呼び出しを同期化する簡単な方法はありますか?

私が考えた唯一の方法は、アニメーションが終了し、このフラグを待つときにフラグをtrueに設定することです。

答えて

24

jQueryは同期アニメーションを作成できません。

JavaScriptはブラウザのUIスレッドで動作します。

同期アニメーションを作成すると、ブラウザはアニメーションが終了するまでフリーズします。

なぜこれを行う必要がありますか?

おそらく、jQueryのコールバックパラメータを使用してこのように、コールバックであなたのメソッドのコードを継続する必要があります

function doSomething() { 
    var thingy = whatever; 
    //Do things 
    $('something').animate({ width: 70 }, function() { 
     //jQuery will call this method after the animation finishes. 
     //You can continue your code here. 
     //You can even access variables from the outer function 
     thingy = thingy.fiddle; 
    }); 
} 

これはクロージャと呼ばれています。

+0

。 –

+8

あなたは間違っています。 'setTimeout'は別のスレッドでコールバックを実行しません。 UIスレッドが空きになるのを待ってから、UIスレッドでコールバックを呼び出します。したがって、Javascriptの開発者は、スレッドセーフな開発の複雑さをすべて処理する必要はありません。 – SLaks

+0

私の答えの解答を試してください – CuSS

1

これは@SLaksに同意します。同期アニメーションを作成するには、特定のアニメーションに対してjQueryのコールバックを使用する必要があります。あなたは、本質的に、あなたの現在のアニメーションのために持っているものは何でも取るなどのようにそれを分割することができます

$yourClass = $('.yourClass'); 
$yourClass.animate({ 
    width: "70%" 
}, 'slow', null, function() { 
    $yourClass.animate({ 
     opacity: 0.4 
    }, 'slow', null, function() { 
     $yourClass.animate({ 
      borderWidth: "10px" 
     }); 
    }); 
}); 
+0

あなたはたぶんそれが20の行動にスケールされるときにどのように見えるか理解しています...また、@SLaksへの私の反応を見てください。 –

+0

見た目が気に入らない場合は、コールバックをインデントしないでください(または、少しインデントしてください)。これが唯一の方法です。 – SLaks

2

jQueryのは、その.animate()メソッドのために、「ステップ」のコールバックを提供します。あなたは、同期アニメーションを行うには、このにフックすることができます

jQuery('#blat').animate({ 
    // CSS to change 
    height: '0px' 
}, 
{ 
    duration: 2000, 
    step: function _stepCallback(now,opts) { 
    // Stop browser rounding errors for bounding DOM values (width, height, margin, etc.) 
    now = opts.now = Math.round(now); 

    // Manipulate the width/height of other elements as 'blat' is animated 
    jQuery('#foo').css({height: now+'px'}); 
    jQuery('#bar').css({width: now+'px'}); 
    }, 
    complete: function _completeCallback() { 
    // Do some other animations when finished... 
    } 
} 
+2

ステップコールバックは質問とは関係ありません。完全なコールバックはまさに​​他の答えが言っているものです。 – SLaks

+0

彼はもう1つのアニメーションが終了した後に1つのアニメーションを実行しようとしています。彼は一度に2つの要素をアニメートしようとしていません。 – SLaks

+0

私の謝罪 - 私の脳は "a"を挿入しました! – shuckster

6

私はあなたがjQueryのqueue()方法を見てみるべきだと思います。

jQueryのアニメーションでは、UIを実際にブロックしておらず、実際にキューを並んでいるだけでなく、

のように、(これは、あなたが「同期」によって何を意味するかの私の最高の理解である)それはまたあなたのアニメーションを作る方法を提供し、機能がシーケンシャル呼び出します。

$("#myThrobber") 
    .show("slow")     // provide user feedback 
    .queue(myNotAnimatedMethod) // do some heavy duty processing 
    .hide("slow");    // provide user feedback (job's 

myNotAnimatedMethod() { // or animated, just whatever you want anyhow... 
    // do stuff 
    // ... 

    // tells #myThrobber's ("this") queue your method "returns", 
    // and the next method in the queue (the "hide" animation) can be processed 
    $(this).dequeue(); 

    // do more stuff here that needs not be sequentially done *before* hide() 
    // 
} 

これは、もちろんやり過ぎです非同期処理を使用します。あなたのメソッドが実際には古くからの同期型のjavascriptメソッドであれば、その方法になる可能性があります。

この情報がお役に立てば幸いです、そして私の下手な英語のため申し訳ありません...

+0

同期が 'fwrite(big_data)'は 'fwrite'が終了した後にAFTERを返します。非同期とは、 'fwrite'が直ちに返ってくることを意味し、大きなデータの書き込みは並列/別の時間に行われます。 –

+0

それから、私は正しいと思います:たとえば、$( "#myThrobber")のアニメーションをfwrite(big_data)の後に同期して実行する場合、次の2つのステートメントでこれを行うことができます: (1)$ "#myThrobber")。キュー(fwrite(big_data))。アニメーション(//何でも); AND (2)$( "#myThrobber")でfwrite()メソッドを終了します。 NB:私のサンプルが間違っていた $(this).dequeue(); それは読む必要があります: $( "#myThrobber")。dequeue(); 私は .queue(jQuery.proxy(myNotAnimatedMethod、this))に必要なコードからそのサンプルを作成したので忘れました その混乱をおかけして申し訳ありません。 –

0

私は本当に使いやすいこのhttp://lab.gracecode.com/motion/ に出くわしたとjQueryとの組み合わせで素晴らしい作品。

EDIT リンクが切れているようです。私が道順アーカイブを正しく追跡した場合、コードはhttps://github.com/feelinglucky/motion

+0

私はそれが英語のドキュメントを持っていたがっています。どうもありがとう。 –

+2

@エラザール:あなたはそれを翻訳することができます。 ) –

0

です。jQueryは同期アニメーションを作成できます。これをチェックしてください:

function DoAnimations(){ 
    $(function(){ 
    $("#myDiv").stop().animate({ width: 70 }, 500); 
    $("#myDiv2").stop().animate({ width: 100 }, 500); 
    }); 
} 
+1

あなたは "function"と "DoAnimations"の間違った綴りを... –

+1

@ChrisFrancisちょうど修正します。 – Mike

+1

これはシーケンシャルで、同期ではありません – SLaks

0

ここでは、アニメーションを順番に実行するのを手助けするために、私がまとめたモジュールです。

使用法:私は、私は間違いなく、シーケンシャルなアニメーションのためのまともな探してコードを持つようにsetTimeout関数でノンブロッキングアニメーションを使用できるようにあなたは、setTimeoutを持つUIスレッドから逃れることができると思い

var seq = [ 
    { id: '#someelement', property:'opacity', initial: '0.0', value:'1.0', duration:500 }, 
    { id: '#somethingelse', property:'opacity', value:'1.0', duration: 500 } 
]; 

Sequencer.runSequence(seq); 

var Sequencer = (function($) { 
    var _api = {}, 
     _seq = {}, 
     _seqCount = 0, 
     _seqCallback = {}; 

    function doAnimation(count, step) { 
     var data = _seq[count][step], 
      props = {}; 

      props[data.property] = data.value 

     $(data.id).animate(props, data.duration, function() { 
      if (step+1 < _seq[count].length) { 
       doAnimation(count, ++step); 
      } else { 
       if (typeof _seqCallback[count] === "function") { 
        _seqCallback[count](); 
       } 
      } 
     }); 
    } 

    _api.buildSequence = function(id, property, initial, steps) { 
     var newSeq = [], 
      step = { 
       id: id, 
       property: property, 
       initial: initial 
      }; 

     $.each(steps, function(idx, s) { 
      step = {}; 
      if (idx == 0) { 
       step.initial = initial; 
      } 
      step.id = id; 
      step.property = property; 
      step.value = s.value; 
      step.duration = s.duration; 
      newSeq.push(step); 
     }); 

     return newSeq; 
    } 

    _api.initSequence = function (seq) { 
     $.each(seq, function(idx, s) {    
      if (s.initial !== undefined) { 
       var prop = {}; 
       prop[s.property] = s.initial; 
       $(s.id).css(prop); 
      }    
     }); 
    } 

    _api.initSequences = function() { 
     $.each(arguments, function(i, seq) { 
      _api.initSequence(seq); 
     }); 
    } 

    _api.runSequence = function (seq, callback) { 
     //if (typeof seq === "function") return; 
     _seq[_seqCount] = []; 
     _seqCallback[_seqCount] = callback; 

     $.each(seq, function(idx, s) { 

      _seq[_seqCount].push(s); 
      if (s.initial !== undefined) { 
       var prop = {}; 
       prop[s.property] = s.initial; 
       $(s.id).css(prop); 
      } 

     }); 


     doAnimation(_seqCount, 0); 
     _seqCount += 1; 
    } 

    _api.runSequences = function() { 
     var i = 0. 
      args = arguments, 
      runNext = function() { 
       if (i+1 < args.length) { 
        i++; 
        if (typeof args[i] === "function") { 
         args[i](); 
         runNext(); 
        } else { 
         _api.runSequence(args[i], function() { 
          runNext(); 
         }); 
        } 
       } 
      }; 

     // first we need to set the initial values of all sequences that specify them 
     $.each(arguments, function(idx, seq) { 
      if (typeof seq !== "function") { 
       $.each(seq, function(idx2, seq2) { 
        if (seq2.initial !== undefined) { 
         var prop = {}; 
         prop[seq2.property] = seq2.initial; 
         $(seq2.id).css(prop); 
        } 
       }); 
      } 

     }); 

     _api.runSequence(arguments[i], function(){ 
      runNext(); 
     }); 

    } 

    return _api; 
}(jQuery)); 
関連する問題