Detener llamada setInterval en JavaScript

1399

Estoy usando setInterval(fname, 10000);para llamar a una función cada 10 segundos en JavaScript. ¿Es posible dejar de llamarlo en algún evento?

Quiero que el usuario pueda detener la actualización repetida de datos.

cnu
fuente

Respuestas:

2160

setInterval()devuelve una ID de intervalo, que puede pasar a clearInterval():

var refreshIntervalId = setInterval(fname, 10000);

/* later */
clearInterval(refreshIntervalId);

Ver los documentos para setInterval()y clearInterval().

John Millikin
fuente
42
¿Cómo puede comenzar de nuevo después de detenerse con 'clearInterval ()'? Si intento reiniciarlo, obtengo el doble de setInterval ejecutándose.
Dan
8
Yo también Cada vez que quiero usar SetInterval (MyFunction, 4000); se vuelve más y más rápido, cada vez 2 veces más rápido :( ¿cómo puedo reiniciar un setinterval?
Alireza Masali
14
SetInterval () no cambia la velocidad a la que lo pasa. Si lo que está haciendo se acelera cada vez que llama a SetInterval (), entonces tiene varios temporizadores que se ejecutan al mismo tiempo y debería abrir una nueva pregunta.
EpicVoyage
29
Asegúrate de realmente detenerlo. Debido al alcance variable, es posible que no tenga el Id. Correcto para llamar clearInterval. He usado en window.refreshIntervalIdlugar de una variable local, ¡y funciona muy bien!
osa
2
He comenzado a adjuntar el controlador setInterval a su elemento asociado (cuando corresponde): $('foo').data('interval', setInterval(fn, 100));y luego lo borré con clearInterval($('foo').data('interval'));Estoy seguro de que también hay una forma no jQuery para hacerlo.
Michael - ¿Dónde está Clay Shirky?
105

Si establece el valor de retorno de setIntervaluna variable, puede usar clearIntervalpara detenerlo.

var myTimer = setInterval(...);
clearInterval(myTimer);
Quintin Robinson
fuente
No veo la diferencia entre esto y la respuesta de John
Bobtroopo
51

Puede establecer una nueva variable y aumentarla en ++ (cuente hasta una) cada vez que se ejecute, luego uso una instrucción condicional para finalizarla:

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);
});

Espero que ayude y sea correcto.

OMGrant
fuente
3
Me sorprendió saber que esto funciona clearInterval(varName);. Esperaba clearIntervalno funcionar cuando pasaba el nombre de la función, pensé que requería la identificación del intervalo. Supongo que esto solo puede funcionar si tiene una función con nombre, ya que no puede pasar una función anónima como una variable dentro de sí misma.
Patrick M
31
En realidad creo que no funciona. El código deja de ejecutarse debido a la restricción en el contador, pero el intervalo sigue disparando varName (). Intente registrar cualquier cosa después de clearInterval () (dentro de la cláusula else) y verá que se escribe para siempre.
Rafael Oliveira
55
Tantos votos a favor por algo que no funciona, a veces no entiendo a las personas en SO: P
Stranded Kid
2
$(document).ready(function(){ });es jQuery, por eso no funciona. Esto debería haber sido mencionado al menos.
paddotk
44
@OMGrant, además de un ejemplo que no funciona, tiene una variable llamada varName, que almacena una función sin nombre , ¿qué? Deberías cambiar o anular esta respuesta, en mi humilde opinión.
Dean Radcliffe
13

Las respuestas anteriores ya explicaron cómo setInterval devuelve un controlador y cómo se utiliza este controlador para cancelar el temporizador de intervalo.

Algunas consideraciones arquitectónicas:

Por favor, no use variables "sin alcance". La forma más segura es usar el atributo de un objeto DOM. El lugar más fácil sería "documento". Si la actualización se inicia con un botón de inicio / parada, puede usar el botón en sí:

<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>

Dado que la función se define dentro del controlador de clic de botón, no tiene que definirla nuevamente. El temporizador se puede reanudar si se vuelve a hacer clic en el botón.

Schien
fuente
1
¿Qué es mejor en ponerlo en documentque en window?
icktoofay
1
corrección. Quise decir document.body. En mi ejemplo de código, estoy usando efectivamente el botón en sí. No hay ID para el botón, pero el puntero "this" está vinculado al parámetro "d" en la función. Usar "ventana" como ámbito es arriesgado porque las funciones también están ahí. Por ejemplo, se puede acceder a "test de función () {}" a través de window.test, que es lo mismo que no usar un ámbito, porque es una abreviatura. Espero que esto ayude.
Schien
1
no pierda las variables "sin alcance" -> no use "sin alcance" Lo habría editado, pero el cambio es inferior a 6 letras y el error es confuso.
Leif Neland
2
No necesitas DOM para eso. Solo nosotros un IIFE para evitar la contaminación de alcance global.
Onur Yıldırım
1
Tengo que agregar 'd.interval = undefined' después de innerhtml = 'start' para que funcione nuevamente. Porque así solo funciona una vez.
jocmtb
11

Ya respondí ... Pero si necesita un temporizador destacado y reutilizable que también sea compatible con múltiples tareas en diferentes intervalos, puede usar mi TaskTimer (para Node y navegador).

// 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();

En su caso, cuando los usuarios hacen clic para alterar la actualización de datos; También puede llamar timer.pause()a continuación, timer.resume()si tienen que volver a habilitar.

Ver más aquí .

Onur Yıldırım
fuente
6

El método clearInterval () se puede usar para borrar un conjunto de temporizadores con el método setInterval ().

setInterval siempre devuelve un valor de ID. Este valor se puede pasar en clearInterval () para detener el temporizador. Aquí hay un ejemplo de temporizador que comienza desde 30 y se detiene cuando se convierte en 0.

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

@cnu,

Puede detener el intervalo, cuando intente ejecutar el código antes de buscar su navegador de consola (F12) ... intente comentar clearInterval (trigger) es buscar nuevamente una consola, no un embellecedor? :PAGS

Consulte el ejemplo de una fuente:

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>

KingRider
fuente
3

Declare la variable para asignar el valor devuelto por setInterval (...) y pase la variable asignada a clearInterval ();

p.ej

var timer, intervalInSec = 2;

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

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

// En cualquier lugar al que tenga acceso al temporizador declarado anteriormente, llame a clearInterval

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

       clearInterval(timer);// Stops or does the work
});
Yergalem
fuente
1
var keepGoing = true;
setInterval(function () {
     if (keepGoing) {
        //DO YOUR STUFF HERE            
        console.log(i);
     }
     //YOU CAN CHANGE 'keepGoing' HERE
  }, 500);

También puede detener el intervalo agregando un detector de eventos a, digamos, un botón con el ID "intervalo de detención":

$('buuton#stop-interval').click(function(){
   keepGoing = false;
});

HTML:

<button id="stop-interval">Stop Interval</button>

Nota: El intervalo se seguirá ejecutando, sin embargo, no pasará nada.

Nadav
fuente
2
Esto es realmente volver a rendimiento, y para las pestañas fondo, en realidad va a reducir la velocidad de los demás temporizadores por mucho desde los temporizadores y los intervalos se regulan para las pestañas fondo
Ferrybig
1

Así es como utilicé el método clearInterval () para detener el temporizador después de 10 segundos.

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>

Ishara Amarasekera
fuente
1

Use setTimeOut para detener el intervalo después de un tiempo.

var interVal = setInterval(function(){console.log("Running")  }, 1000);
 setTimeout(function (argument) {
    clearInterval(interVal);
 },10000);
Syed Shibli
fuente
0

Supongo que el siguiente código ayudará:

var refreshIntervalId = setInterval(fname, 10000);

clearInterval(refreshIntervalId);

Hiciste el código 100% correcto ... Entonces ... ¿Cuál es el problema? O es un tutorial ...

Juego peligroso
fuente
-3

¿Por qué no usar un enfoque más simple? Añadir una clase!

Simplemente agregue una clase que le diga al intervalo que no haga nada. Por ejemplo: en vuelo estacionario.

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>

He estado buscando este enfoque rápido y fácil durante años, por lo que publico varias versiones para presentarle a la mayor cantidad de personas posible.

Aart den Braber
fuente
17
No me parece más simple ... También creo que es más limpio eliminar sus intervalos en lugar de mantener llamadas a funciones que no hacen nada.
Romain Braun
No estoy de acuerdo this.setInterval(function() { if(!$('#counter').hasClass('pauseInterval')) { //do something } }, 500);es todo lo que tienes para el código. Además, el cheque es lo primero que debe hacer, por lo que es muy liviano cuando está suspendido. Para eso es esto: pausar temporalmente una función . Si desea terminarlo indefinidamente: por supuesto, elimina el intervalo.
Aart den Braber
Esto equivale a encuestas y generalmente se desaconseja. Despertará la CPU de estados de baja potencia solo para hacer una (inútil) verificación inútil. También retrasa la retroalimentación de inmediato a entre 0 y 500 ms en este ejemplo.
Charlie
No estoy totalmente de acuerdo con usted, incluso mientras escribí el código hace 2 años. El contador debe estar allí de todos modos, porque el OP lo solicitó. Claro, si está usando esto para detener el contador después de presionar un botón, por ejemplo, esta sería una solución subóptima, pero solo para una pausa al pasar el mouse, esta es una de las soluciones más simples disponibles.
Aart den Braber