Canceling/Stopping a callback function from executing in jQuery/Javascript
I have开发者_开发技巧 an animation that is set to play after a timeout. This animation repeats itself over on different elements after it completes. I'm utilizing the animate
method's callback function to initiate the next animation. My extracted code looks like:
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
);
}
On a click event, I want the animations to stop. At any given time, the "fancyAnimation" function is queued to run, which just queues it again and again and so forth.
Is there a way that I can stop this function from executing, thereby ending the infinite loop on a certain event? If so, how would you do this?
Thank you so much!
EDIT: By request, the code that initiates fancyAnimation
.
function initiateFancyAnimation() {
animation_timeout = setTimeout( "fancyAnimation()", animation_interval );
}
Well, the easy way would be to set a global flag that you check each time the function runs:
var runAnimation;
function fancyAnimation() {
if (runAnimation) {
// your function body as written
}
}
$('#start').click(function() {
runAnimation = true;
fancyAnimation();
});
$('#stop').click(function() {
runAnimation = false;
});
You could apply a certain class to the 'dot' when the user clicks the item and then check for that class on each loop like this:
$('#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
);
}
}
EDIT:
An alternative that I've used in the past is a plugin called $.doTimeout which allows for the callback to be controlled a little better.
With this plugin you could do something like this:
$.doTimeout('timeoutID', 3000, function() {
// Check for Global Run True / False Flag //
if (runAnimation){
fancyAnimation();
}
});
Not sure if this helps as the callback is still run; however it would allow you to pause the actual animation function from running.
Now that functional reactive programming has arrived, here's one way to do it in this style using BaconJS (though it's not any shorter).
$('#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");
});
});
Working demo at http://jsfiddle.net/ronaldchanou/o4hk0176/2/
精彩评论