【问题标题】:Universal Animation Queue in jQuery?jQuery中的通用动画队列?
【发布时间】:2012-07-10 02:32:28
【问题描述】:

我正在尝试创建这种滑动效果,但我遇到的唯一问题是排队。

$(this).animate({'left' : '0%'}, randTime, function() {
    $(this).animate({'boxShadow' : 'none'});
    setTimeout(function() {
        $container.children('.slice').addClass('noshadow');
        $('body > div:not(#'+container+') .slice').each(function() {
            restartAnimation($(this));
        });             
    $container.children('.content').fadeIn();   
    }, (aLength+100));
});

上面的容器变量是当前容器。我做了 :not(container) 所以当前容器会继续动画。这一切都在一个具有两个属性的函数中,即容器元素的 ID 和动画将要运行的方式(只是关键字通过 if 语句运行)。然后我会有一个菜单来激活这样的动画:

if($(this).attr('name') == 'home') {

    animation('home', 'top');

}
else if { .....

重新启动动画功能只是将所有其他动画元素重新启动到它们的原始位置,以便它们可以再次运行。现在,问题是,在重新启动功能运行之前存在延迟,因此如果您在延迟时间内单击两个菜单项,您最终会运行重新启动功能,然后一切都会变得很混乱。

我需要一种将动画重新启动到其原始位置的方法,以便它可以再次运行,但不会干扰和重新启动其他动画元素。否则我们最终会陷入巨大的混乱。我已经设置了一个快速的 jsFiddle,所以你可以试试效果。这段代码现在有点乱,我打算等我完成后把所有的东西都整理一下,但是这个排队问题真的让我卡住了。 http://jsfiddle.net/qe7dj/

【问题讨论】:

  • boxShadow 可以动画吗?还是您想使用 .css()?

标签: javascript jquery


【解决方案1】:

解决这个问题的一种方法是在第一个动画完成之前不允许另一个动画开始。

可能有几种方法可以做到这一点,但想到的一种是创建一个全局函数队列对象(我将在下面给出解释和代码)。

您需要一个全局变量来跟踪当前动画幻灯片的数量。

var animationsRunning = 0;

每次幻灯片动画开始时,递增上述变量。当幻灯片动画结束时,将其递减。

现在,在开始(多张幻灯片的)全新动画之前,请检查该变量。如果幻灯片当前正在制作动画,请将动画函数添加到全局函数队列中。如果没有,请照常运行动画。

if ($(this).attr('name') == 'home') {
    if (animationsRunning < 1) {
        animation('home', 'top');
    }
    else {
        funqueue.push(wrapFunction(animation, this, ['home', 'top']));
    }
}
else if ($(this).attr('name') == 'about') {
    if (animationsRunning < 1) {
        animation('about', 'left');
    }
    else {
        funqueue.push(wrapFunction(animation, this, ['about', 'left']));
    }
}

else if ($(this).attr('name') == 'services') {
    if (animationsRunning < 1) {
        animation('services', 'hslide');
    }
    else {
        funqueue.push(wrapFunction(animation, this, ['services', 'hslide']));
    }
}

每次所有幻灯片完成动画时,检查全局函数队列中是否有任何项目。如果有,执行第一个。

if (animationsRunning < 1 && funqueue.length > 0) {
    (funqueue.shift())();
}

函数队列相关代码如下:

// Function wrapping code.
// fn - reference to function.
// context - what you want "this" to be.
// params - array of parameters to pass to function.
var wrapFunction = function(fn, context, params) {
    return function() {
        fn.apply(context, params);
    };
};

// Global function queue
var funqueue = [];

Stack Overflow question here对全局函数队列的概念有很好的解释,这里就不详细解释了。

可以在here 找到一个有效的 jsfiddle 示例。

编辑:

您可能希望防止等待动画的累积 - 如果是这种情况,您可以在添加最新项目之前简单地清除函数队列。显然,在这种情况下您实际上并不需要队列,但我将其保留为与第一个解决方案兼容。

更新的 jsFiddle 位于 here

【讨论】:

  • 这很完美!我尝试了动画停止的东西,但我不知道如何处理队列或任何东西。非常感谢。
猜你喜欢
  • 2013-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多