Is there a way to clear all time outs from a given window? I suppose the timeouts are stored somewhere in the window
object but couldn't confirm that.
Any cross browser solution is welcome.
Is there a way to clear all time outs from a given window? I suppose the timeouts are stored somewhere in the window
object but couldn't confirm that.
Any cross browser solution is welcome.
They are not in the window object, but they have ids, which (afaik) are consecutive integers.
So you may clear all timeouts like so:
var id = window.setTimeout(function() {}, 0);
while (id--) {
window.clearTimeout(id); // will do nothing if no timeout with id is present
}
I think the easiest way to accomplish this would be to store all the setTimeout
identifiers in one array, where you can easily iterate to clearTimeout()
on all of them.
var timeouts = [];
timeouts.push(setTimeout(function(){alert(1);}, 200));
timeouts.push(setTimeout(function(){alert(2);}, 300));
timeouts.push(setTimeout(function(){alert(3);}, 400));
for (var i=0; i<timeouts.length; i++) {
clearTimeout(timeouts[i]);
}
This is very late... but:
Basically, setTimeout/setInterval ID's go in consecutive order, so just create a dummy timeout function to get the highest ID, then clear interval on all the IDs lower than that.
const highestId = window.setTimeout(() => {
for (let i = highestId; i >= 0; i--) {
window.clearInterval(i);
}
}, 0);
I have an addition to Pumbaa80's answer that might be useful for someone developing for old IEs.
Yes, all major browsers implement timeout ids as consecutive integers (which is not required by specification). Althrough the starting number differs form browser to browser. It seems that Opera, Safari, Chrome and IE > 8 starts timeout ids from 1, Gecko-based browsers from 2 and IE <= 8 from some random number that is magically saved across tab refresh. You can discover it yourself.
All that meens that in IE <=8 the while (lastTimeoutId--)
cycle may run over 8digits times and show the "A script on this page is causing Internet Explorer to run slowly" message. So if you can not save all you timeout id's or don't want to override window.setTimeout you may consider saving the first timeout id on a page and clearing timeouts until it.
Execute the code on early page load:
var clearAllTimeouts = (function () {
var noop = function () {},
firstId = window.setTimeout(noop, 0);
return function () {
var lastId = window.setTimeout(noop, 0);
console.log('Removing', lastId - firstId, 'timeout handlers');
while (firstId != lastId)
window.clearTimeout(++firstId);
};
});
And then clear all pending timeouts that probably was set by foreign code so many times you want
How about store the timeout ids in a global array, and define a method to delegate the function call to the window's.
GLOBAL={
timeouts : [],//global timeout id arrays
setTimeout : function(code,number){
this.timeouts.push(setTimeout(code,number));
},
clearAllTimeout :function(){
for (var i=0; i<this.timeouts.length; i++) {
window.clearTimeout(this.timeouts[i]); // clear all the timeouts
}
this.timeouts= [];//empty the id array
}
};
You have to rewrite the window.setTimeout
method and save its timeout ID.
const timeouts = [];
const originalTimeoutFn = window.setTimeout;
window.setTimeout = function(fun, delay) { //this is over-writing the original method
const t = originalTimeoutFn(fn, delay);
timeouts.push(t);
}
function clearTimeouts(){
while(timeouts.length){
clearTimeout(timeouts.pop());
}
}
Place the below code before any other script and it will create a wrapper function for the original setTimeout
& clearTimeout
.
New clearTimeouts
methods will be added to the window
Object, which will allow clearing all (pending) timeouts (Gist link).
Other answers lack complete support for possible arguments
setTimeout
might receive.
// isolated layer wrapper (for the local variables)
(function(_W){
var cache = [], // will store all timeouts IDs
_set = _W.setTimeout, // save original reference
_clear = _W.clearTimeout // save original reference
// Wrap original setTimeout with a function
_W.setTimeout = function( CB, duration, arg ){
// also, wrap the callback, so the cache reference will be removed
// when the timeout has reached (fired the callback)
var id = _set(function(){
removeCacheItem(id)
CB.apply(null, arguments)
}, duration || 0, arg)
cache.push(id) // store reference in the cache array
// id reference must be returned to be able to clear it
return id
}
// Wrap original clearTimeout with a function
_W.clearTimeout = function( id ){
_clear(id)
removeCacheItem(id)
}
// Add a custom function named "clearTimeouts" to the "window" object
_W.clearTimeouts = function(){
console.log("Clearing " + cache.length + " timeouts")
cache.forEach(n => _clear(n))
cache.length = []
}
// removes a specific id from the cache array
function removeCacheItem( id ){
var idx = cache.indexOf(id)
if( idx > -1 )
cache = cache.filter(n => n != id )
}
})(window);
// lets define some timeouts
setTimeout(()=> console.log('1s passed'), 1000); // should run
setTimeout(()=> console.log('2s passed'), 2000); // should be cleared
setTimeout(()=> console.log('3s passed'), 3000); // should be cleared
// lets clear them all after 1 and a half second:
setTimeout(()=> {
window.clearTimeouts()
}, 1500)
See a nice piece of code which I named "better-timeout" which does a bit more than the above.
For completeness, I wanted to post a general solution that covers both setTimeout
and setInterval
.
It seems browsers might use the same pool of IDs for both, but from some of the answers to Are clearTimeout and clearInterval the same?, it's not clear whether it's safe to rely on clearTimeout
and clearInterval
performing the same function or only working on their respective timer types.
Therefore, when the goal is to kill all timeouts and intervals, here's an implementation that might be slightly more defensive across implementations when unable to test all of them:
function clearAll(windowObject) {
var id = Math.max(
windowObject.setInterval(noop, 1000),
windowObject.setTimeout(noop, 1000)
);
while (id--) {
windowObject.clearTimeout(id);
windowObject.clearInterval(id);
}
function noop(){}
}
You can use it to clear all timers in the current window:
clearAll(window);
Or you can use it to clear all timers in an iframe
:
clearAll(document.querySelector("iframe").contentWindow);
I use Vue with Typescript.
private setTimeoutN;
private setTimeoutS = [];
public myTimeoutStart() {
this.myTimeoutStop();//stop All my timeouts
this.setTimeoutN = window.setTimeout( () => {
console.log('setTimeout');
}, 2000);
this.setTimeoutS.push(this.setTimeoutN)//add THIS timeout ID in array
}
public myTimeoutStop() {
if( this.setTimeoutS.length > 0 ) {
for (let id in this.setTimeoutS) {
console.log(this.setTimeoutS[id]);
clearTimeout(this.setTimeoutS[id]);
}
this.setTimeoutS = [];//clear IDs array
}
}
We've just published a package solving this exact issue.
npm install time-events-manager
With that, you can view all timeouts and intervals via timeoutCollection
& intervalCollection
objects.
There's also a removeAll
function which clears all timeouts/intervals both from the collection and the browser.
Inside the setTimeout after the definition of function f(...){} and timeout can be additional parameters.
For example: $setTimeout( function(a, b){ run(a); run(b); }, 100, a, b); )
...args solves that problem.
var $timeouts = new Array();
function $setTimeout(...args)
{
var t = window.setTimeout(...args);
$timeouts.push(t);
return t;
}
function $clearTimeout(id)
{
if( $timeouts.indexOf(id) > -1 )
$timeouts = $timeouts.filter(n => n != id )
window.clearTimeout(id);
}
function $clearTimeouts()
{
while($timeouts.length)
window.clearTimeout($timeouts.pop());
}
For old browsers you need to use another methods to pass parameters and to delete a value from the array $timeouts.
var $timeouts = new Array();
function $setTimeout()
{
var t = window.setTimeout.apply( this, arguments );
$timeouts.push(t);
return t;
}
function $clearTimeout(id)
{
var index = $timeouts.indexOf(id);
if (index > -1) {
$timeouts.splice(index, 1);
}
window.clearTimeout(id);
}
function $clearTimeouts()
{
while($timeouts.length)
window.clearTimeout($timeouts.pop());
}
The answers of the other are actually correct. But for me this is how approach this kind of stuff. Check my code bellow.
// example when I person types on search input
function typeOnSearch(time = 3000) {
// this will clear timeout
clearTimeout(window.typeOnSearchTimeOut);
// we create a timeout variable and added it to window, this way, we can access this in any function in our app.
window.typeOnSearchTimeOut = setTimeout( () => {
//enter what you like to do here, like fetch data
}, time);
}
Use a global timeout which all of your other functions derive timing from. This will make everything run faster, and be easier to manage, although it will add some abstraction to your code.