1745

I am using setInterval(fname, 10000); to call a function every 10 seconds in JavaScript. Is it possible to stop calling it on some event?

I want the user to be able to stop the repeated refresh of data.

Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345
cnu
  • 36,135
  • 23
  • 65
  • 63

9 Answers9

2687

setInterval() returns an interval ID, which you can pass to clearInterval():

var refreshIntervalId = setInterval(fname, 10000);

/* later */
clearInterval(refreshIntervalId);

See the docs for setInterval() and clearInterval().

its4zahoor
  • 1,709
  • 1
  • 16
  • 23
John Millikin
  • 197,344
  • 39
  • 212
  • 226
  • 58
    How can you start it again after stopping with 'clearInterval()'? If I try to restart it I get 2x the setInterval running. – Dan Apr 02 '12 at 15:37
  • 11
    Me too Each time That i want to use SetInterval(MyFunction , 4000); it get faster and faster , each time 2x time faster :( how can i restart a setinterval?? – Alireza Masali Feb 03 '13 at 13:15
  • 18
    SetInterval() does not change the speed that you pass it. If whatever it is doing speeds up each time that you call SetInterval(), then you have multiple timers which are running at the same time, and should open a new question. – EpicVoyage Apr 12 '13 at 11:14
  • 43
    Make sure you are really stopping it. Because of variable scoping, you may not have the right Id to call `clearInterval`. I have used `window.refreshIntervalId` instead of a local variable, and it works great! – Sergey Orshanskiy Oct 15 '13 at 04:10
  • couldn't I use `this` inside the `fname`? – Jürgen Paul Dec 04 '13 at 10:22
  • same. `var interval;` inside of Singleton -- `fn start(){ interval = setInterval(localFnToMethod, 1000) }` -- `fn restart(){ clearInterval(interval); start(); }`... gets me running batches of the same "`start`" method... ??? – Cody Jan 14 '15 at 02:25
  • @PineappleUndertheSea yes, you can do that, you can define the id and then call to clearInternal inside fname without problems. – carzogliore Feb 03 '15 at 04:56
  • 3
    I have started attaching the setInterval handle to its associated element (when relevant): `$('foo').data('interval', setInterval(fn, 100));` and then clearing it with `clearInterval($('foo').data('interval'));` I'm sure there is a non-jQuery way to do it, too. – Michael Feb 24 '17 at 17:14
  • 1
    SetInterval exists and runs in the global scope of the window. When you assign a setInterval id to a local variable, the local variable is overwritten when the page refreshes and the setInterval is orphaned in the global scope. You no longer have a reference to its id but it continues to run. The fix is to put the variable, in this case, 'refreshIntervalId' into the global scope. That means don't use var to declare it. – Dieter Donnert Mar 31 '19 at 21:00
136

If you set the return value of setInterval to a variable, you can use clearInterval to stop it.

var myTimer = setInterval(...);
clearInterval(myTimer);
Hatchet
  • 5,320
  • 1
  • 30
  • 42
Quintin Robinson
  • 81,193
  • 14
  • 123
  • 132
68

You can set a new variable and have it incremented by ++ (count up one) every time it runs, then I use a conditional statement to end it:

var intervalId = null;
var varCounter = 0;
var varName = function(){
     if(varCounter <= 10) {
          varCounter++;
          /* your code goes here */
     } else {
          clearInterval(intervalId);
     }
};

$(document).ready(function(){
     intervalId = setInterval(varName, 10000);
});

I hope that it helps and it is right.

Blauharley
  • 4,186
  • 6
  • 28
  • 47
OMGrant
  • 977
  • 6
  • 2
  • 5
    I was surprised to learn that this works `clearInterval(varName);`. I expected `clearInterval` to not work when passed the function name, I thought it required the interval ID. I suppose this can only work if you have a named function, as you can't pass an anonymous function as a variable inside of itself. – Patrick M Aug 15 '12 at 17:24
  • 34
    Actually I think it doesn't works. The code stop being executed because of the restriction on the counter, but the interval keeps firing varName(). Try to log anything after clearInterval() (inside the else clause) and you will see it being written forever. – Rafael Oliveira Apr 10 '13 at 15:14
  • Rafael Oliveira is right it doesn't stop the interval at all it is still running but the condition is not met. – Morfidon Apr 30 '15 at 14:13
  • 3
    `$(document).ready(function(){ });` is jQuery, that's why it doesn't work. This should've been mentioned at least. – paddotk Jun 16 '15 at 15:07
  • 5
    @OMGrant, In addition to an example that does not work, you have a variable named `varName`, which stores an unnamed function - wha?? You should change or take down this answer, IMHO. – Dean Radcliffe Sep 26 '15 at 12:58
  • Variable names aside, the answer has the right idea. Store the returned value of `setInterval`, looping and incrementing a counter, and when that counter maxes out, you `clearInterval` with the id from earlier. It works. – TankorSmash Aug 18 '16 at 23:31
  • 1
    As the MSN makes very clear, clearInterval expects an id not a function: https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearInterval. Due to this answer being incorrect as well as misleading I'm voting it down. – sidewinderguy Sep 28 '16 at 20:30
  • If you assign the intervalId on the global window object I believe it will work. – RayLoveless Feb 23 '22 at 22:01
14

Already answered... But if you need a featured, re-usable timer that also supports multiple tasks on different intervals, you can use my TaskTimer (for Node and browser).

// Timer with 1000ms (1 second) base interval resolution.
const timer = new TaskTimer(1000);

// Add task(s) based on tick intervals.
timer.add({
    id: 'job1',         // unique id of the task
    tickInterval: 5,    // run every 5 ticks (5 x interval = 5000 ms)
    totalRuns: 10,      // run 10 times only. (omit for unlimited times)
    callback(task) {
        // code to be executed on each run
        console.log(task.name + ' task has run ' + task.currentRuns + ' times.');
        // stop the timer anytime you like
        if (someCondition()) timer.stop();
        // or simply remove this task if you have others
        if (someCondition()) timer.remove(task.id);
    }
});

// Start the timer
timer.start();

In your case, when users click for disturbing the data-refresh; you can also call timer.pause() then timer.resume() if they need to re-enable.

See more here.

Onur Yıldırım
  • 32,327
  • 12
  • 84
  • 98
11

In nodeJS you can you use the "this" special keyword within the setInterval function.

You can use this this keyword to clearInterval, and here is an example:

setInterval(
    function clear() {
            clearInterval(this) 
       return clear;
    }()
, 1000)

When you print the value of this special keyword within the function you output a Timeout object Timeout {...}

assayag.org
  • 709
  • 10
  • 24
5

The Trick

setInterval returns a number:

enter image description here

Solution

Take this number. Pass it to the function clearInterval and you're safe:

enter image description here

Code:

Always store the returned number of setInterval in a variable, so that you can stop the interval later on:

const intervalID = setInterval(f, 1000);

// Some code

clearInterval(intervalID);

(Think of this number as the ID of a setInterval. Even if you have called many setInterval, you can still stop anyone of them by using the proper ID.)

underflow
  • 1,545
  • 1
  • 5
  • 19
1
const interval = setInterval(function() {
     const checkParticlesjs = document.querySelector('.success_class')  // get success_class from page
     if (checkParticlesjs) {  // check if success_class exist
         fbq('track', 'CompleteRegistration');  // Call Facebook Event
         clearInterval(interval);  // Stop Interval 
        }
 }, 2000); // repeat every 2 second
Mohamed Raafat
  • 122
  • 1
  • 5
0

Use this if you have your counter in a button onclick.

<button onClick="inter = setInterval(myCounter, 1000)">start to count</button>

<p id="demo">here is the counter</p>

<button onClick="clearInterval(inter)">stop </button>
Gero
  • 12,993
  • 25
  • 65
  • 106
-4

Why not use a simpler approach? Add a class!

Simply add a class that tells the interval not to do anything. For example: on hover.

var i = 0;
this.setInterval(function() {
  if(!$('#counter').hasClass('pauseInterval')) { //only run if it hasn't got this class 'pauseInterval'
    console.log('Counting...');
    $('#counter').html(i++); //just for explaining and showing
  } else {
    console.log('Stopped counting');
  }
}, 500);

/* In this example, I'm adding a class on mouseover and remove it again on mouseleave. You can of course do pretty much whatever you like */
$('#counter').hover(function() { //mouse enter
    $(this).addClass('pauseInterval');
  },function() { //mouse leave
    $(this).removeClass('pauseInterval');
  }
);

/* Other example */
$('#pauseInterval').click(function() {
  $('#counter').toggleClass('pauseInterval');
});
body {
  background-color: #eee;
  font-family: Calibri, Arial, sans-serif;
}
#counter {
  width: 50%;
  background: #ddd;
  border: 2px solid #009afd;
  border-radius: 5px;
  padding: 5px;
  text-align: center;
  transition: .3s;
  margin: 0 auto;
}
#counter.pauseInterval {
  border-color: red;  
}
<!-- you'll need jQuery for this. If you really want a vanilla version, ask -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<p id="counter">&nbsp;</p>
<button id="pauseInterval">Pause</button></p>

I've been looking for this fast and easy approach for ages, so I'm posting several versions to introduce as many people to it as possible.

Aart den Braber
  • 864
  • 1
  • 11
  • 23
  • 17
    Doesn't seem really simpler to me... I also think it is cleaner to remove your intervals instead of keeping calls to functions that do nothing. – Romain Braun Apr 27 '15 at 18:06
  • I don't agree. `this.setInterval(function() { if(!$('#counter').hasClass('pauseInterval')) { //do something } }, 500);` is all you have for code. Moreover, the check is the first thing you do, so it's very lightweight when it's being hovered. That is what this one is for: **temporarily pausing a function**. If you want to terminate it indefinitely: of course you remove the interval. – Aart den Braber Apr 30 '15 at 07:49
  • This amounts to polling and is generally discouraged. It will wake up the CPU from low power states just to do a (likely) useless check. It also delays feedback from immediate to between 0 and 500 ms in this example. – Charlie Apr 20 '17 at 07:58
  • I entirely don't agree with you, even while I wrote the code 2 years ago. The counter must be there anyway, because the OP asked for it. Sure, if you're using this to stop the counter after pressing a button, for example, this would be a sub-optimal solution, but just for a pause when hovering, this is one of the simplest solutions available. – Aart den Braber Apr 30 '17 at 18:19
  • A bit late, but just want to note why I'm downvoting. Please consider using a real MRE (minimal reproducible example) that is fit for the question, there's far too much noise here. – Seth Falco Apr 06 '23 at 12:27