JQuery同步动画

发布于 2024-08-07 20:22:29 字数 143 浏览 4 评论 0原文

在很多情况下我希望动画能够同步执行。特别是当我想制作一系列连续动画时。

有没有一种简单的方法可以使 jQuery animate 函数调用同步?

我想到的唯一方法是在动画完成时将标志设置为 true 并等待该标志。

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 jQuery animate function call synchronous?

The only way I thought about is to set a flag true when the animation has finished and to wait for this flag.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

木緿 2024-08-14 20:22:29

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

这称为闭包。

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.

慕巷 2024-08-14 20:22:29

我认为你应该看看 jQuery queue() 方法。

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 方法,那么这可能就是实现它的方法。

希望这有帮助,抱歉我的英语不好......

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...

冰火雁神 2024-08-14 20:22:29

jQuery 为其 .animate() 方法提供了“step”回调。您可以连接它来执行同步动画:

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...
  }
}

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...
  }
}
听闻余生 2024-08-14 20:22:29

在这一点上我同意@SLaks 的观点。您应该使用给定动画的 jQuery 回调来创建同步动画。您基本上可以采用当前动画中的任何内容并将其拆分,如下所示:

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

I agree with @SLaks on this one. You should be using jQuery's callbacks for given animations to create your synchronous animation. You can essentially take whatever you have for your current animation and split it up like so:

$yourClass = $('.yourClass');
$yourClass.animate({
    width: "70%"
}, 'slow', null, function() {
    $yourClass.animate({
        opacity: 0.4
    }, 'slow', null, function() {
        $yourClass.animate({
            borderWidth: "10px"
        });
    });
});
美男兮 2024-08-14 20:22:29

这是我不久前组装的一个模块,用于帮助按顺序运行动画。

用法:

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

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));
方觉久 2024-08-14 20:22:29

jQuery 可以制作同步动画。看看这个:

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

jQuery can make synchronous animations. Check this out:

function DoAnimations(){
  $(function(){
    $("#myDiv").stop().animate({ width: 70 }, 500);
    $("#myDiv2").stop().animate({ width: 100 }, 500);
  });
}
夜光 2024-08-14 20:22:29

我遇到了这个 http://lab.gracecode.com/motion/
真的很容易使用,并且与 jquery 结合使用效果很好。

编辑
链接似乎已死。如果我正确地跟踪了那些回程存档,代码位于 https://github.com/feelinglucky /动作

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文