2011-10-11 122 views
1

我有一个动画设置为在超时后播放。该动画在完成后在不同的元素上重复。我正在利用animate方法的回调函数来启动下一个动画。我提取的代码如下所示:取消/停止在jQuery/Javascript中执行回调函数

function fancyAnimation() { 
    // Get a random object property, which is actually the id for a dot 
    var id = getRandomNumber(1, 100); 

    // Apply an effect to the dot 
    $('#test' + id).effect(
     'pulsate', 
     { times : 3 }, 
     1000, 
     fancyAnimation 
    ); 
} 

在点击事件中,我希望动画停止。在任何时候,“fancyAnimation”函数都是排队等待运行的,它只是一次又一次地排队等等。

有没有办法阻止这个函数执行,从而结束某个事件的无限循环?如果是这样,你会如何做到这一点?

非常感谢!

编辑:根据请求,启动fancyAnimation的代码。

function initiateFancyAnimation() { 
    animation_timeout = setTimeout("fancyAnimation()", animation_interval); 
} 
+0

显示我们调用'fancyAnimation代码()'。 –

+0

@MattBall - 启动代码在那里。在这种情况下,这应该不重要;然而,因为我只是在排队后寻找一种方法来停止“fancyAnimation”。我不确定没有重构就有可能。 – tollmanz

+0

在调用新的递归之前,fancyanimation()中的控制语句(if)会起作用。例如:一个布尔变量,通过超时事件设置为true,通过点击事件设置为false。作为评论发布,因为我不知道这是否可能在JavaScript中。 – supertopi

回答

2

好了,简单的方法是设置你的每个函数运行时检查全局标志:

var runAnimation; 

function fancyAnimation() { 
    if (runAnimation) { 
     // your function body as written 
    } 
} 

$('#start').click(function() { 
    runAnimation = true; 
    fancyAnimation(); 
}); 

$('#stop').click(function() { 
    runAnimation = false; 
}); 
+0

嗯,这证实了我的方法;)这正是我所做的,但由于某种原因,它只是感觉错了,所以我正在寻找另一种方法。有没有困难的方式,但也许更好的方式? – tollmanz

+0

不是真的:)。我知道的真正取消回调的唯一方法是将该功能重新分配给无操作,例如, 'fancyAnimation = $ .noop'。但是这会阻止你再次运行它,除非你在其他地方有一个参考 - 在这种情况下我不认为它是一个好的选择。 – nrabinowitz

0

您可以应用某一类的“点”,用户点击时项目,然后检查该类别在每次循环是这样的:

$('#button').click(function(){ 
    $('#targetDot').addClass('stop'); 
}); 

function fancyAnimation() {  
// Get a random object property, which is actually the id for a dot 
    var id = getRandomNumber(1, 100); 

    // Check for Class and Execute ONLY is .stop is not found // 
    if ($(id).hasClass('stop') !== true){ 
     // Apply an effect to the dot 
     $('#test' + id).effect(
      'pulsate', 
      { times : 3 }, 
      1000, 
      fancyAnimation 
     ); 
    } 
} 

编辑:

一种替代我过去使用的是一个叫做$.doTimeout的插件,它可以让回调得到更好的控制。

有了这个插件,你可以做这样的事情:

$.doTimeout('timeoutID', 3000, function() { 
    // Check for Global Run True/False Flag // 
    if (runAnimation){ 
     fancyAnimation(); 
    } 
}); 

不知道这是否有助于为回调仍然运行;但是它可以让你暂停运行中的实际动画功能。

+0

感谢您的建议!这是一个聪明的方法。不幸的是,我正在寻找任何有关能够阻止该功能执行的信息。我在想这是不可能的,但我想至少我会问。 – tollmanz

0

现在功能反应式编程已经到来,下面是使用BaconJS(尽管它不会更短)以这种方式完成它的一种方法。

$('#start').click(function(){ 
    // open event bus 
    var eventBus = new Bacon.Bus(); 

    // tell eventBus to run animation every time it receives event 
    eventBus.onValue(function(){ 
     fancyAnimation(); 
    }); 

    // push initial event to start animation immediately 
    eventBus.push(); 

    // continue to push events at interval 
    eventBus.plug(Bacon.fromPoll(animation_interval, function(){ 
     return new Bacon.Next(); 
    })); 

    $("#start").attr("disabled", "disabled"); 
    $("#stop").removeAttr("disabled"); 

    // tell eventBus to end when stop is clicked 
    $('#stop').click(function(){ 
     eventBus.end(); 

     $("#stop").attr("disabled", "disabled"); 
     $("#start").removeAttr("disabled"); 
    }); 
}); 

工作演示在http://jsfiddle.net/ronaldchanou/o4hk0176/2/