JQuery synchronous animation

前端 未结 7 1894
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-11-29 07:00

In many cases I wish animation to be executed synchronously. Especially when I wish to make a a series of sequential animations.

Is there an easy way to make a jQuer

相关标签:
7条回答
  • 2020-11-29 07:06

    jQuery provides a "step" callback for its .animate() method. You can hook into this to do synchronous animations:

    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...
      }
    }
    
    0 讨论(0)
  • 2020-11-29 07:10

    jQuery cannot make synchronous animations.

    Remember that JavaScript runs on the browser's UI thread.

    If you make a synchronous animation, the browser will freeze until the animation finishes.

    Why do you need to do this?

    You should probably use jQuery's callback parameter and continue your method code in the callback, like this:

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

    This is called a closure.

    0 讨论(0)
  • 2020-11-29 07:12

    jQuery can make synchronous animations. Check this out:

    function DoAnimations(){
      $(function(){
        $("#myDiv").stop().animate({ width: 70 }, 500);
        $("#myDiv2").stop().animate({ width: 100 }, 500);
      });
    }
    
    0 讨论(0)
  • 2020-11-29 07:13

    I think you should take a look at the jQuery queue() method.

    Not only does queue()'s doc explain jQuery animations don't really block the UI, and actually queues them after one another.

    It also provides with a way to make your animations and function calls sequential (this is my best understanding of what you mean by "synchronous"), like:

    $("#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()
        // 
    }  
    

    This is of course overkill with asynchronous processing; but if your method is actually a plain old synchronous javascript method, that could be the way to do it.

    Hope this helps, and sorry for my poor english...

    0 讨论(0)
  • 2020-11-29 07:15

    I came across this http://lab.gracecode.com/motion/ Really easy to use and works great in combination with jquery.

    EDIT The links seems dead. If I've followed the trail those the wayback archive correctly, the code is at https://github.com/feelinglucky/motion

    0 讨论(0)
  • 2020-11-29 07:19

    Here is a module i put together a while back to assist in running animations sequentially.

    Usage:

    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 讨论(0)
提交回复
热议问题