Beenden Sie den Aufruf von setInterval in JavaScript

1398

Ich verwende setInterval(fname, 10000);, um alle 10 Sekunden eine Funktion in JavaScript aufzurufen. Ist es möglich, den Anruf bei einem Ereignis zu beenden?

Ich möchte, dass der Benutzer die wiederholte Aktualisierung von Daten stoppen kann.

cnu
quelle

Antworten:

2160

setInterval()Gibt eine Intervall-ID zurück, an die Sie übergeben können clearInterval():

var refreshIntervalId = setInterval(fname, 10000);

/* later */
clearInterval(refreshIntervalId);

Siehe die Dokumente für setInterval()und clearInterval().

John Millikin
quelle
42
Wie können Sie es erneut starten, nachdem Sie mit 'clearInterval ()' gestoppt haben? Wenn ich versuche, es neu zu starten, wird das setInterval zweimal ausgeführt.
Dan
8
Ich auch jedes Mal, wenn ich SetInterval (MyFunction, 4000) verwenden möchte; es wird immer schneller, jedes Mal 2x schneller :( Wie kann ich ein Setinterval neu starten?
Alireza Masali
14
SetInterval () ändert nicht die Geschwindigkeit, mit der Sie es übergeben. Wenn sich das, was auch immer es tut, jedes Mal beschleunigt, wenn Sie SetInterval () aufrufen, haben Sie mehrere Timer, die gleichzeitig ausgeführt werden, und sollten eine neue Frage öffnen.
EpicVoyage
29
Stellen Sie sicher, dass Sie es wirklich stoppen. Aufgrund des variablen Bereichs haben Sie möglicherweise nicht die richtige ID zum Aufrufen clearInterval. Ich habe window.refreshIntervalIdanstelle einer lokalen Variablen verwendet, und es funktioniert großartig!
osa
2
Ich habe damit begonnen, das setInterval-Handle an das zugehörige Element anzuhängen (falls relevant): $('foo').data('interval', setInterval(fn, 100));und es dann mit zu löschen. clearInterval($('foo').data('interval'));Ich bin sicher, dass es auch eine Nicht-jQuery-Möglichkeit gibt, dies zu tun.
Michael - Wo ist Clay Shirky
105

Wenn Sie den Rückgabewert setIntervaleiner Variablen festlegen , können Sie ihn clearIntervalstoppen.

var myTimer = setInterval(...);
clearInterval(myTimer);
Quintin Robinson
quelle
Ich sehe keinen Unterschied zwischen dieser und Johns Antwort
Bobtroopo
51

Sie können eine neue Variable festlegen und sie bei jeder Ausführung um ++ (eine hochzählen) erhöhen lassen. Dann verwende ich eine bedingte Anweisung, um sie zu beenden:

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

Ich hoffe, dass es hilft und es richtig ist.

OMGrant
quelle
3
Ich war überrascht zu erfahren, dass dies funktioniert clearInterval(varName);. Ich habe erwartet clearInterval, dass es nicht funktioniert, wenn der Funktionsname übergeben wird. Ich dachte, es erfordert die Intervall-ID. Ich nehme an, dies kann nur funktionieren, wenn Sie eine benannte Funktion haben, da Sie eine anonyme Funktion nicht als Variable in sich selbst übergeben können.
Patrick M
31
Eigentlich denke ich, dass es nicht funktioniert. Der Code wird aufgrund der Einschränkung des Zählers nicht mehr ausgeführt, aber das Intervall löst weiterhin varName () aus. Versuchen Sie, alles nach clearInterval () (innerhalb der else-Klausel) zu protokollieren, und Sie werden sehen, dass es für immer geschrieben wird.
Rafael Oliveira
5
So viele Upvotes für etwas, das nicht funktioniert, manchmal verstehe ich Leute auf SO: P
Stranded Kid am
2
$(document).ready(function(){ });ist jQuery, deshalb funktioniert es nicht. Dies hätte zumindest erwähnt werden sollen.
Paddotk
4
@OMGrant, Zusätzlich zu einem Beispiel, das nicht funktioniert, haben Sie eine Variable mit dem Namen varName, in der eine unbenannte Funktion gespeichert ist - was? Sie sollten diese Antwort ändern oder notieren, IMHO.
Dean Radcliffe
13

In den obigen Antworten wurde bereits erläutert, wie setInterval ein Handle zurückgibt und wie dieses Handle zum Abbrechen des Intervall-Timers verwendet wird.

Einige architektonische Überlegungen:

Bitte verwenden Sie keine Variablen ohne Gültigkeitsbereich. Am sichersten ist es, das Attribut eines DOM-Objekts zu verwenden. Der einfachste Ort wäre "Dokument". Wenn die Auffrischung über eine Start / Stopp-Taste gestartet wird, können Sie die Taste selbst verwenden:

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

Da die Funktion im Button-Click-Handler definiert ist, müssen Sie sie nicht erneut definieren. Der Timer kann fortgesetzt werden, wenn die Schaltfläche erneut angeklickt wird.

Schien
quelle
1
Was ist besser daran, es anzuziehen documentals an window?
icktoofay
1
Korrektur. Ich wollte document.body sagen. In meinem Codebeispiel verwende ich effektiv die Schaltfläche selbst. Es gibt keine ID für die Schaltfläche, aber der Zeiger "this" ist an den Parameter "d" in der Funktion gebunden. Die Verwendung von "Fenster" als Gültigkeitsbereich ist riskant, da auch Funktionen vorhanden sind. Auf "function test () {}" kann beispielsweise über window.test zugegriffen werden. Dies entspricht der Tatsache, dass überhaupt kein Bereich verwendet wird, da es sich um eine Kurzform handelt. Hoffe das hilft.
Schien
1
Verlieren Sie keine "scope-less" -Variablen -> verwenden Sie nicht "scope-less". Ich hätte es bearbeitet, aber die Änderung ist kleiner als 6 Buchstaben und der Fehler ist verwirrend.
Leif Neland
2
Dafür brauchst du kein DOM. Nur wir ein IIFE, um globale Verschmutzung zu vermeiden.
Onur Yıldırım
1
Ich muss 'd.interval = undefined' nach innerhtml = 'start' hinzufügen, damit es wieder funktioniert. Denn so funktioniert es nur einmal.
Jocmtb
11

Bereits beantwortet ... Wenn Sie jedoch einen vorgestellten, wiederverwendbaren Timer benötigen, der auch mehrere Aufgaben in unterschiedlichen Intervallen unterstützt, können Sie meinen TaskTimer (für Knoten und Browser) verwenden.

// 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 Ihrem Fall, wenn Benutzer klicken, um die Datenaktualisierung zu stören. Sie können auch anrufen timer.pause()dann , timer.resume()wenn sie müssen wieder aktivieren.

Sehen Sie hier mehr .

Onur Yıldırım
quelle
6

Mit der Methode clearInterval () kann ein mit der Methode setInterval () festgelegter Timer gelöscht werden.

setInterval gibt immer einen ID-Wert zurück. Dieser Wert kann in clearInterval () übergeben werden, um den Timer zu stoppen. Hier ist ein Beispiel für einen Timer, der bei 30 beginnt und stoppt, wenn er 0 wird.

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

@cnu,

Sie können das Intervall stoppen, wenn Sie versuchen, Code auszuführen, bevor Sie Ihren Konsolenbrowser (F12) suchen ... versuchen Sie es mit einem Kommentar clearInterval (Trigger). : P.

Überprüfen Sie beispielsweise eine Quelle:

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

Deklarieren Sie die Variable, um den von setInterval (...) zurückgegebenen Wert zuzuweisen, und übergeben Sie die zugewiesene Variable an clearInterval ().

z.B

var timer, intervalInSec = 2;

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

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

// Überall dort, wo Sie Zugriff auf den oben angegebenen Timer haben , rufen Sie clearInterval auf

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

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

Sie können das Intervall auch stoppen, indem Sie einen Ereignis-Listener hinzufügen, um beispielsweise eine Schaltfläche mit der ID "Stoppintervall" zu erstellen:

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

HTML:

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

Hinweis: Das Intervall wird weiterhin ausgeführt, es wird jedoch nichts passieren.

Nadav
quelle
2
Dies ist wirklich zurück für die Leistung, und für Hintergrund-Tabs wird es tatsächlich alle anderen Timer um ein Vielfaches verlangsamen, da Timer und Intervalle für Hintergrund-Tabs gedrosselt werden
Ferrybig
1

So habe ich die clearInterval () -Methode verwendet, um den Timer nach 10 Sekunden anzuhalten.

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

Verwenden Sie setTimeOut, um das Intervall nach einiger Zeit anzuhalten.

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

Ich denke, der folgende Code wird helfen:

var refreshIntervalId = setInterval(fname, 10000);

clearInterval(refreshIntervalId);

Sie haben den Code zu 100% korrigiert ... Also ... Was ist das Problem? Oder es ist ein Tutorial ...

Gefährliches Spiel
quelle
-3

Warum nicht einen einfacheren Ansatz verwenden? Fügen Sie eine Klasse hinzu!

Fügen Sie einfach eine Klasse hinzu, die das Intervall anweist, nichts zu tun. Zum Beispiel: beim Schweben.

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>

Ich habe seit Ewigkeiten nach diesem schnellen und einfachen Ansatz gesucht, daher veröffentliche ich mehrere Versionen, um so viele Menschen wie möglich daran zu erinnern.

Aart den Braber
quelle
17
Scheint mir nicht wirklich einfacher zu sein ... Ich denke auch, dass es sauberer ist, Ihre Intervalle zu entfernen, anstatt Funktionen aufzurufen, die nichts bewirken.
Romain Braun
Ich stimme nicht zu this.setInterval(function() { if(!$('#counter').hasClass('pauseInterval')) { //do something } }, 500);ist alles, was Sie für Code haben. Darüber hinaus ist der Check das erste, was Sie tun, so dass er sehr leicht ist, wenn er schwebt. Dafür ist dieser gedacht: eine Funktion vorübergehend anhalten . Wenn Sie es auf unbestimmte Zeit beenden möchten: Natürlich entfernen Sie das Intervall.
Aart den Braber
Dies ist eine Umfrage und wird im Allgemeinen nicht empfohlen. Die CPU wird aus dem Energiesparmodus geweckt, um eine (wahrscheinlich) nutzlose Überprüfung durchzuführen. In diesem Beispiel wird die Rückmeldung von sofort auf 0 bis 500 ms verzögert.
Charlie
Ich stimme Ihnen überhaupt nicht zu, obwohl ich den Code vor 2 Jahren geschrieben habe. Der Schalter muss sowieso da sein, weil das OP danach gefragt hat. Sicher, wenn Sie dies verwenden, um den Zähler nach dem Drücken einer Taste anzuhalten, wäre dies eine suboptimale Lösung, aber nur für eine Pause beim Schweben ist dies eine der einfachsten verfügbaren Lösungen.
Aart den Braber