8

What's the proper way to cancel all JS setTimeout , setInterval and requestAnimationFrame after a given amount of seconds ?

Edit: Sorry, I should have explained more! The code comes from either Database or some API, so I cannot keep track of the timeout,raf or interval IDs. So I don't have the IDs of the timers that I can easily you to clearInterval or clearTimeout or cancelAnimationFrame. I know I have to use them, but I don't know how to get all the animation IDs (if there are any).

Ram
  • 143,282
  • 16
  • 168
  • 197
user1437328
  • 15,546
  • 9
  • 34
  • 44
  • 1
    possible duplicate of http://stackoverflow.com/questions/3141064/how-to-stop-all-timeouts-and-intervals-using-javascript – Patrick Oscity Jul 07 '12 at 10:24
  • In that case it's not possible to cancel them. The only other thing you could do is overwrite the functions they refer to, provided the setTimeout calls have been provided named function references. Overwrite each referenced function with a new empty function and nothing will happen when the timeout occurs. – Graham Jul 07 '12 at 10:26
  • 4
    in the post i linked to in the above comment, there is an answer that redefines the methods `setInterval` and `setTimeout` and automatically registers those in a global list, which is then used to clear all of them. It may be very interesting for your purpose. – Patrick Oscity Jul 07 '12 at 10:27

2 Answers2

15

You need to keep the Id of each interval, timeout and requestAnimationFrame you've created and call window.clearInterval(id) etc. on them.

A verfy hackish/brute force way to do it would be something like:

for (var i = 1; i < 99999; i++) {
    window.clearInterval(i);
    window.clearTimeout(i);
    window.mozCancelAnimationFrame(i); // Firefox
}

But I wouldn't recommend that.

Update:

To do it after a certain amount of time:

setTimeout(function () {
   for (var i = 1; i < 99999; i++) {
        window.clearInterval(i);
        window.clearTimeout(i);
        window.mozCancelAnimationFrame(i); // Firefox
    }
}, 3000); // After 3 seconds

Update 2:

I don't believe there is a better way than the brute force way if you don't keep a reference for each time out etc, so to make it a bit easier to do that (as suggested by this SO answer), you could override the default setInterval:

var intervals = new Array();
window.oldSetInterval = window.setInterval;
window.setInterval = function(func, interval) {
    intervals.push(oldSetInterval(func, interval));
}

// Now you can loop over intervals and clear them 
// one by one when ever you want to.

for (var interval in intervals) {
   window.clearInterval(interval);
}

The example shows how to do it for setInterval, but could of course be done the same way on setTimeout and requestAnimationFrame as well.

Community
  • 1
  • 1
Christofer Eliasson
  • 32,939
  • 7
  • 74
  • 103
  • indeed, I feel like it's a very hacking way. Would love to know a better approach. – user1437328 Jul 07 '12 at 10:25
  • @user1437328 Why can you not store all of the id's? I'm afraid there is no better way, without keeping a reference to each timeout etc. – Christofer Eliasson Jul 07 '12 at 10:27
  • 1
    Your update number 2 is pretty clever. You went from a hackish solution to an optimized one. thanks! – Oscar Ortiz Apr 30 '14 at 00:20
  • this is quite useful when you do not have access to the original code, for example, in a autoload jquery code: `$(function(){ setInterval(function(){ /** ... **/ }, 10); });` I have not found another way to get the interval instance :( – UselesssCat Sep 28 '17 at 19:02
1

You'll need to obtain references to each timeout (the return value of setTimeout) then use clearTimeout() then you wish you cancel them. Same for setInterval.

Graham
  • 6,484
  • 2
  • 35
  • 39