web-dev-qa-db-ja.com

JQuery同期アニメーション

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

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

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

20

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;
    });
}

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

26
SLaks

JQuery queue() メソッドを見てみるべきだと思います。

Queue()のドキュメントでは、jQueryアニメーションが実際にはUIをブロックしないことを説明しているだけでなく、実際にはそれらを次々にキューに入れています。

また、次のように、アニメーションと関数呼び出しをシーケンシャルにする方法も提供します(これは、「synchronous」の意味を最もよく理解しています)。

$("#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メソッドである場合は、それがその方法である可能性があります。

これがお役に立てば幸いです、そして私の貧弱な英語をお詫びします...

6
Alain BECKER

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
shuckster

これについては@SLaksに同意します。同期アニメーションを作成するには、特定のアニメーションに対してjQueryのコールバックを使用する必要があります。基本的に、現在のアニメーションに使用しているものをすべて取得して、次のように分割できます。

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

私はこれに出くわしました http://lab.gracecode.com/motion/ 本当に使いやすく、jqueryと組み合わせるとうまく機能します。

[〜#〜]編集[〜#〜]リンクが切れているようです。ウェイバックアーカイブの軌跡を正しくたどった場合、コードは https://github.com/feelinglucky/motion にあります。

0
John van Dijk

これは、アニメーションを順番に実行するのを支援するために、しばらく前にまとめたモジュールです。

使用法:

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));
0

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

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