Fenster: setInterval()-Methode
Baseline
Weitgehend verfügbar
*
Diese Funktion ist gut etabliert und funktioniert auf vielen Geräten und in vielen Browserversionen. Sie ist seit Juli 2015 browserübergreifend verfügbar.
* Einige Teile dieser Funktion werden möglicherweise unterschiedlich gut unterstützt.
Warnung:
Wenn der code-Parameter verwendet wird, führt diese Methode ihren Wert dynamisch als JavaScript aus.
Solche APIs sind als Injection-Sinks bekannt und stellen potenziell einen Vektor für Cross-Site-Scripting (XSS)-Angriffe dar.
Sie können dieses Risiko mindern, indem Sie stets TrustedScript-Objekte anstelle von Zeichenfolgen zuweisen und vertrauenswürdige Typen erzwingen.
Siehe Sicherheitsüberlegungen für weitere Informationen.
Die setInterval()-Methode der Window-Schnittstelle ruft wiederholt eine Funktion auf oder führt einen Code-Schnipsel aus, mit einer festen Zeitverzögerung zwischen jedem Aufruf.
Syntax
setInterval(code)
setInterval(code, delay)
setInterval(func)
setInterval(func, delay)
setInterval(func, delay, param1)
setInterval(func, delay, param1, param2)
setInterval(func, delay, param1, param2, /* …, */ paramN)
Parameter
func-
Eine
Function, die alledelayMillisekunden ausgeführt wird. Die erste Ausführung erfolgt nachdelayMillisekunden. code-
Ein
TrustedScriptoder eine Zeichenfolge von beliebigem Code, der alledelayMillisekunden kompiliert und ausgeführt wird. Dies kann anstelle einer Funktion verwendet werden, wird aber dringend abgeraten, aus den gleichen Gründen, die die Verwendung voneval()zu einem Sicherheitsrisiko machen. delayOptional-
Die Verzögerungszeit zwischen den Ausführungen der angegebenen Funktion oder des Codes, in Millisekunden. Standardmäßig 0, wenn nicht angegeben. Siehe Verzögerungsbeschränkungen unten für Details zum erlaubten Bereich der
delay-Werte. param1, …,paramNOptional-
Zusätzliche Argumente, die an die durch func spezifizierte Funktion übergeben werden, sobald der Timer abläuft.
Rückgabewert
Eine positive Ganzzahl (typischerweise im Bereich von 1 bis 2.147.483.647), die den durch den Aufruf erstellten Intervall-Timer eindeutig identifiziert.
Dieser Bezeichner, oft als "Intervall-ID" bezeichnet, kann an clearInterval() übergeben werden, um die wiederholte Ausführung der angegebenen Funktion zu stoppen.
Ausnahmen
SyntaxError-
Der
codekann nicht als Skript geparst werden. TypeError-
Wird ausgelöst, wenn der
code-Parameter auf eine Zeichenfolge gesetzt ist, während Trusted Types von einer CSP erzwungen werden und keine Standardrichtlinie definiert ist. Es wird auch ausgelöst, wenn der erste Parameter nicht einer der unterstützten Typen ist: eine Funktion, Zeichenfolge oderTrustedScript.
Beschreibung
Die setInterval()-Funktion wird häufig verwendet, um eine Verzögerung für Funktionen festzulegen, die immer wieder ausgeführt werden, wie z. B. Animationen.
Sie können das Intervall mit clearInterval() abbrechen.
Wenn Sie wünschen, dass Ihre Funktion einmal nach der angegebenen Verzögerung aufgerufen wird, verwenden Sie setTimeout().
Verzögerungsbeschränkungen
Es ist möglich, dass Intervalle verschachtelt werden; das bedeutet, dass der Rückruf für setInterval() seinerseits setInterval() aufrufen kann, um ein weiteres Intervall zu starten, obwohl das erste noch läuft.
Um den potenziellen Einfluss auf die Leistung zu mindern, erzwingt der Browser automatisch einen minimalen Wert von 4 ms für das Intervall, wenn Intervalle über fünf Ebenen tief verschachtelt sind.
Versuche, einen Wert von weniger als 4 ms in tief verschachtelten Aufrufen von setInterval() anzugeben, werden auf 4 ms festgesetzt.
Browser können in bestimmten Umständen sogar noch strengere Mindestwerte für das Intervall durchsetzen, obwohl diese nicht häufig auftreten sollten.
Beachten Sie auch, dass die tatsächliche Zeitspanne zwischen den Aufrufen des Rückrufs länger sein kann als das angegebene delay; schauen Sie sich Gründe für längere Verzögerungen als angegeben für Beispiele an.
Hinweis:
Das delay-Argument wird in eine signierte 32-Bit-Ganzzahl umgewandelt, was den Wert auf 2147483647 ms oder etwa 24,8 Tage beschränkt.
Intervall-IDs werden mit setTimeout() geteilt
Die Methode gibt einen Bezeichner zurück, der den durch den Aufruf erstellten Intervall-Timer eindeutig identifiziert.
Dieser Bezeichner, der oft als "Intervall-ID" bezeichnet wird, kann an clearInterval() übergeben werden, um die wiederholte Ausführung der angegebenen Funktion zu stoppen.
Innerhalb derselben globalen Umgebung (z.B. ein bestimmtes Fenster oder Worker) bleibt die Intervall-ID eindeutig und wird nicht für irgendeinen neuen Intervall-Timer wiederverwendet, solange der ursprüngliche Timer noch aktiv ist. Jedoch halten unterschiedliche globale Umgebungen ihre eigenen unabhängigen Pools von Intervall-IDs.
Beachten Sie, dass setInterval() und setTimeout() denselben Pool von IDs teilen und dass clearInterval() und clearTimeout() technisch austauschbar verwendet werden können.
Zur Klarheit sollten Sie jedoch versuchen, sie immer zuzuordnen, um Verwirrung bei der Wartung Ihres Codes zu vermeiden.
Sicherstellen, dass die Ausführungsdauer kürzer als die Intervallfrequenz ist
Wenn die Möglichkeit besteht, dass Ihre Logik länger dauern könnte als die Intervallzeit, wird empfohlen, dass Sie eine benannte Funktion rekursiv mit setTimeout() aufrufen.
Zum Beispiel, wenn Sie setInterval() verwenden, um alle 5 Sekunden einen Remote-Server abzufragen, könnten Netzwerkverzögerungen, ein nicht antwortender Server und eine Vielzahl anderer Probleme verhindern, dass die Anfrage in der zugewiesenen Zeit abgeschlossen wird.
In solchen Fällen könnten Sie auf aufgestaute XHR-Anfragen stoßen, die nicht unbedingt in Reihenfolge zurückkehren.
In diesen Fällen wird ein rekursives setTimeout()-Muster bevorzugt:
(function loop() {
setTimeout(() => {
// Your logic here
loop();
}, delay);
})();
Im obigen Code-Schnipsel wird eine benannte Funktion loop() deklariert und sofort ausgeführt.
loop() wird rekursiv innerhalb von setTimeout() aufgerufen, nachdem die Logik abgeschlossen ist.
Obwohl dieses Muster keine garantierte Ausführung in einem festen Intervall gewährleistet, stellt es sicher, dass das vorherige Intervall abgeschlossen ist, bevor es rekursiv aufgerufen wird.
Funktionen werden mit dem globalen this aufgerufen
Die an setInterval() übergebenen Funktionen werden mit normalen Funktionsaufrufsemantiken ausgeführt, um die Referenz von this zu bestimmen.
Dieses Problem wird im JavaScript-Referenz im Detail erklärt.
Für Nicht-Arrow-Funktionen wird der this-Kontext auf das globalThis (ein Alias für window in Browsern) Objekt gesetzt.
Das folgende Beispiel zeigt, wie dies unerwartetes Verhalten verursachen kann. Hier, wenn wir die Methode counter.count direkt an setInterval() übergeben, geht der this-Kontext verloren und die Methode wird auf dem globalen Objekt anstelle der Counter-Instanz aufgerufen, was zu einem TypeError führt, wenn die count-Methode versucht, auf this zuzugreifen:
class Counter {
constructor() {
this.data = new Map();
}
count(item) {
this.data.set(item, (this.data.get(item) || 0) + 1);
}
}
const counter = new Counter();
counter.count("foo"); // Successfully adds "foo" to the map
setInterval(counter.count, 1000, "bar");
// TypeError: Cannot read properties of undefined (reading 'set')
Um dies zu umgehen, müssen Sie sicherstellen, dass die an setInterval übergebene Funktion den korrekten this-Kontext hat. Es gibt drei Hauptmethoden, dies zu erreichen:
-
Wenn Sie den
this-Kontext ausdrücklich angeben möchten, anstatt die Methode direkt zu übergeben, wickeln Sie den Methodenaufruf in eine andere anonyme Funktion, die die Methode mit dem korrekten Kontext ausdrücklich aufruft:jssetInterval(() => counter.count("bar"), 1000); setInterval(function () { counter.count("bar"); }, 1000); -
Wenn Sie den
this-Kontext des Codes verwenden möchten, dersetInterval()aufruft, nutzen Sie immer eine Arrow-Funktion, die denthis-Kontext ihres umgebenden Scope erbt:jsclass Counter { // … repeatedCount(item) { // BAD: the `this` context is lost in the callback setInterval(function () { this.data.set(item, (this.data.get(item) || 0) + 1); }, 1000); } }jsclass Counter { // … repeatedCount(item) { // GOOD: the arrow function inherits the `this` context of `repeatedCount()` setInterval(() => { this.data.set(item, (this.data.get(item) || 0) + 1); }, 1000); } } -
Wenn Sie zusätzliche Funktions-Wrapper vermeiden möchten (die den Speicherverbrauch erhöhen) und gleichzeitig den
this-Kontext ausdrücklich festlegen möchten, können Sie die MethodeFunction.prototype.bind()verwenden, um eine neue Funktion mit dem korrektenthis-Kontext zu erstellen:jssetInterval(counter.count.bind(counter), 1000, "bar");
Sicherheitsüberlegungen
Die Methode kann verwendet werden, um beliebige Eingaben, die im code-Parameter übergeben werden, auszuführen.
Wenn die Eingabe eine potenziell unsichere Zeichenfolge von einem Benutzer ist, ist dies ein möglicher Vektor für Cross-Site-Scripting (XSS)-Angriffe.
Zum Beispiel zeigt der folgende Code, wie setInterval() möglicherweise untrustedCode, bereitgestellt von einem Benutzer, ausführt:
const untrustedCode = "alert('Potentially evil code!');";
const id = setInterval(untrustedCode, 1000);
Websites mit einer Content Security Policy (CSP), die script-src oder default-src spezifizieren, verhindern, dass ein solcher Code standardmäßig ausgeführt wird.
Sie können unsafe-eval in Ihrer CSP spezifizieren, um die Ausführung von setInterval() zu erlauben, aber das ist unsicher, da es einen der Hauptschutzmechanismen der CSP deaktiviert.
Siehe Inline JavaScript im CSP-Leitfaden.
Wenn Sie zulassen müssen, dass die Skripte über setInterval() ausgeführt werden, können Sie diese Probleme mildern, indem Sie stets TrustedScript-Objekte anstelle von Zeichenfolgen zuweisen und vertrauenswürdige Typen erzwingen mittels der require-trusted-types-for-CSP-Direktive.
Dies stellt sicher, dass die Eingabe durch eine Transformationsfunktion geleitet wird.
Um setInterval() auszuführen, müssen Sie zusätzlich das trusted-types-eval Keyword in Ihrer CSP script-src Direktive angeben.
Dies wirkt auf die gleiche Weise wie unsafe-eval, erlaubt aber nur, dass die Methode ausgeführt wird, wenn vertrauenswürdige Typen aktiviert sind (wenn Sie unsafe-eval verwenden würden, würde es die Ausführung auch in Browsern erlauben, die keine vertrauenswürdigen Typen unterstützen).
Zum Beispiel, die erforderliche CSP für Ihre Website könnte folgendermaßen aussehen:
Content-Security-Policy: require-trusted-types-for 'script'; script-src '<your_allowlist>' 'trusted-types-eval'
Das Verhalten der Transformationsfunktion hängt vom spezifischen Anwendungsfall ab, der ein vom Benutzer bereitgestelltes Skript erfordert. Wenn möglich, sollten Sie die erlaubten Skripte genau auf den Code beschränken, dem Sie vertrauen, dass er ausgeführt werden darf. Wenn das nicht möglich ist, könnten Sie die Verwendung bestimmter Funktionen innerhalb der bereitgestellten Zeichenfolge erlauben oder blockieren.
Beispiele
Beachten Sie, dass diese Beispiele zur Klarheit auf die Verwendung vertrauenswürdiger Typen verzichten.
Siehe Verwendung von TrustedScript in eval() für Code, der den erwarteten Ansatz zeigt.
Beispiel 1: Grundlegende Syntax
Das folgende Beispiel demonstriert die grundlegende Syntax von setInterval().
const intervalID = setInterval(myCallback, 500, "Parameter 1", "Parameter 2");
function myCallback(a, b) {
// Your code here
// Parameters are purely optional.
console.log(a);
console.log(b);
}
Beispiel 2: Wechsel zwischen zwei Farben
Das folgende Beispiel ruft die Funktion flashtext() einmal pro Sekunde auf, bis die Stopptaste gedrückt wird.
HTML
<div id="my_box">
<h3>Hello World</h3>
</div>
<button id="start">Start</button>
<button id="stop">Stop</button>
CSS
.go {
color: green;
}
.stop {
color: red;
}
JavaScript
// variable to store our intervalID
let intervalId;
function changeColor() {
// check if an interval has already been set up
intervalId ??= setInterval(flashText, 1000);
}
function flashText() {
const oElem = document.getElementById("my_box");
oElem.className = oElem.className === "go" ? "stop" : "go";
}
function stopTextColor() {
clearInterval(intervalId);
// release our intervalId from the variable
intervalId = null;
}
document.getElementById("start").addEventListener("click", changeColor);
document.getElementById("stop").addEventListener("click", stopTextColor);
Ergebnis
Spezifikationen
| Spezifikation |
|---|
| HTML> # dom-setinterval-dev> |