1542
votes

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.

17

17 Answers

2382
votes

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().

118
votes

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

var myTimer = setInterval(...);
clearInterval(myTimer);
56
votes

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.

14
votes

The answers above have already explained how setInterval returns a handle, and how this handle is used to cancel the Interval timer.

Some architectural considerations:

Please do not use "scope-less" variables. The safest way is to use the attribute of a DOM object. The easiest place would be "document". If the refresher is started by a start/stop button, you can use the button itself:

<a onclick="start(this);">Start</a>

<script>
function start(d){
    if (d.interval){
        clearInterval(d.interval);
        d.innerHTML='Start';
    } else {
        d.interval=setInterval(function(){
          //refresh here
        },10000);
        d.innerHTML='Stop';
    }
}
</script>

Since the function is defined inside the button click handler, you don't have to define it again. The timer can be resumed if the button is clicked on again.

11
votes

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.

9
votes

The clearInterval() method can be used to clear a timer set with the setInterval() method.

setInterval always returns a ID value. This value can be passed in clearInterval() to stop the timer. Here is an example of timer starting from 30 and stops when it becomes 0.

  let time = 30;
  const timeValue = setInterval((interval) => {
  time = this.time - 1;
  if (time <= 0) {
    clearInterval(timeValue);
  }
}, 1000);
7
votes

@cnu,

You can stop interval, when try run code before look ur console browser (F12) ... try comment clearInterval(trigger) is look again a console, not beautifier? :P

Check example a source:

var trigger = setInterval(function() { 
  if (document.getElementById('sandroalvares') != null) {
    document.write('<div id="sandroalvares" style="background: yellow; width:200px;">SandroAlvares</div>');
    clearInterval(trigger);
    console.log('Success');
  } else {
    console.log('Trigger!!');
  }
}, 1000);
<div id="sandroalvares" style="background: gold; width:200px;">Author</div>
3
votes

Declare variable to assign value returned from setInterval(...) and pass the assigned variable to clearInterval();

e.g.

var timer, intervalInSec = 2;

timer = setInterval(func, intervalInSec*1000, 30 ); // third parameter is argument to called function 'func'

function func(param){
   console.log(param);
}

// Anywhere you've access to timer declared above call clearInterval

$('.htmlelement').click( function(){  // any event you want

       clearInterval(timer);// Stops or does the work
});
3
votes

This is how I used clearInterval() method to stop the timer after 10 seconds.

function startCountDown() {
  var countdownNumberEl = document.getElementById('countdown-number');
  var countdown = 10;
  const interval = setInterval(() => {
    countdown = --countdown <= 0 ? 10 : countdown;
    countdownNumberEl.textContent = countdown;
    if (countdown == 1) {
      clearInterval(interval);
    }
  }, 1000)
}
<head>
  <body>
    <button id="countdown-number" onclick="startCountDown();">Show Time </button>
  </body>
</head>
1
votes

Use setTimeOut to stop the interval after some time.

var interVal = setInterval(function(){console.log("Running")  }, 1000);
 setTimeout(function (argument) {
    clearInterval(interVal);
 },10000);
1
votes

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 outpout a Timeout object Timeout {...}

1
votes

So many people have given their nice answer, clearInterval is the correct solution.

But I think we can do more, to let our editor enforces the best practice with javascript timers.

It is always easy to forget to clear the timers set up by setTimeout or setInterval, which can cause bugs that are uneasy to find out.

So I've created an eslint plugin for the problem above.

https://github.com/littlee/eslint-plugin-clean-timer

0
votes

I guess the following code will help:

var refreshIntervalId = setInterval(fname, 10000);

clearInterval(refreshIntervalId);

You did the code 100% correct... So... What's the problem? Or it's a tutorial...

0
votes

Try

let refresch = ()=>  document.body.style= 'background: #'
  +Math.random().toString(16).slice(-6);

let intId = setInterval(refresch, 1000);

let stop = ()=> clearInterval(intId);
body {transition: 1s}
<button onclick="stop()">Stop</button>
-1
votes

clearInterval()

Note, you can start and pause your code with this capability. The name is a bit deceptive, since it says CLEAR, but it doesn't clear anything. It actually pauses.

Test with this code:

HTML:

<div id='count'>100</div>
<button id='start' onclick='start()'>Start</button>
<button id='stop' onclick='stop()'>Stop</button>

JavaScript:

let count;

function start(){
 count = setInterval(timer,100)  /// HERE WE RUN setInterval()
}

function timer(){
  document.getElementById('count').innerText--;
}


function stop(){
  clearInterval(count)   /// here we PAUSE  setInterval()  with clearInterval() code
}
-1
votes

var interval = setInterval(timer, 100);
var n = 0;

function timer() {
  n = n + 0.1
  document.getElementById('show').innerHTML = n.toFixed(2)
}
function pause() {
  clearInterval(interval)
}
function resume(){
  interval = setInterval(timer, 100)
}
<h1 id="show">0</h1>
<button id="btn" onclick="pause()">STOP</button>
<button id="btn" onclick="resume()">RESUME</button>
-2
votes

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.