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 bekannt als Injection Points und sind potenziell ein Vektor für Cross-Site-Scripting (XSS) Angriffe.
Sie können dieses Risiko mindern, indem Sie immer TrustedScript Objekte anstelle von Zeichenfolgen zuweisen und vertrauenswürdige Typen durchsetzen.
Siehe Sicherheitsüberlegungen für weitere Informationen.
Die setInterval() Methode des Fenster Interfaces ruft wiederholt eine Funktion auf oder führt ein Code-Snippet 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 mit beliebigem Code, der alledelayMillisekunden kompiliert und ausgeführt wird. Dies kann anstelle einer Funktion verwendet werden, wird aber stark davon abgeraten, da die Verwendung voneval()ein Sicherheitsrisiko darstellt. delayOptional-
Die Zeitverzögerung 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 über den zulässigen Bereich der
delayWerte. param1, …,paramNOptional-
Zusätzliche Argumente, die an die durch func spezifizierte Funktion übergeben werden, sobald der Timer abläuft.
Rückgabewert
Eine positive ganze Zahl (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 wird, während vertrauenswürdige Typen durch eine 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 Funktion setInterval() 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 möchten, dass Ihre Funktion einmal nach der angegebenen Verzögerung aufgerufen wird, verwenden Sie setTimeout().
Verzögerungsbeschränkungen
Es ist möglich, dass Intervalle geschachtelt sind; das heißt, der Rückruf für setInterval() kann seinerseits setInterval() aufrufen, um ein weiteres Intervall zu starten, auch wenn das erste noch läuft.
Um die potenziellen Auswirkungen auf die Leistung zu mildern, erzwingt der Browser automatisch einen Mindestwert von 4 ms für das Intervall, sobald Intervalle über fünf Ebenen hinaus geschachtelt sind.
Versuche, einen Wert von weniger als 4 ms in tief geschachtelten Aufrufen von setInterval() anzugeben, werden auf 4 ms festgelegt.
Browser können unter bestimmten Umständen noch strengere Mindestwerte für das Intervall durchsetzen, obwohl dies nicht häufig vorkommen sollte.
Beachten Sie auch, dass die tatsächliche Zeit, die zwischen den Aufrufen des Rückrufs vergeht, länger sein kann als die angegebene delay; siehe Gründe für längere Verzögerungen als angegeben für Beispiele.
Hinweis:
Das delay-Argument wird in eine signierte 32-Bit-Ganzzahl konvertiert, die den Wert auf 2147483647 ms begrenzt, was ungefähr 24,8 Tagen entspricht.
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 einen neuen Intervall-Timer wiederverwendet, solange der ursprüngliche Timer noch aktiv ist. Verschiedene globale Umgebungen führen jedoch 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.
Um jedoch Verwirrung bei der Wartung Ihres Codes zu vermeiden, sollten Sie versuchen, sie immer passend zu verwenden.
Sicherstellen, dass die Ausführungsdauer kürzer als die Intervallfrequenz ist
Wenn die Möglichkeit besteht, dass Ihre Logik länger dauert als die Intervallzeit, wird empfohlen, rekursiv eine benannte Funktion mit setTimeout() aufzurufen.
Wenn Sie z. B. setInterval() verwenden, um alle 5 Sekunden einen Remote-Server zu pollen, könnten Netzwerklatenz, ein nicht reagierender Server und viele andere Probleme verhindern, dass die Anfrage in ihrer vorgesehenen Zeit abgeschlossen wird.
Daher könnten Sie in einer Situation mit einer Schlange von XHR-Anfragen enden, die möglicherweise nicht in der richtigen Reihenfolge zurückkehren.
In solchen Fällen ist ein rekursives setTimeout()-Muster vorzuziehen:
(function loop() {
setTimeout(() => {
// Your logic here
loop();
}, delay);
})();
Im obigen Code-Snippet wird eine benannte Funktion loop() deklariert und sofort ausgeführt.
loop() wird rekursiv innerhalb von setTimeout() aufgerufen, nachdem die Logik vollständig ausgeführt wurde.
Während dieses Muster keine Ausführung in einem festen Intervall garantiert, stellt es sicher, dass das vorherige Intervall abgeschlossen ist, bevor es erneut aufgerufen wird.
Funktionen werden mit dem globalen this aufgerufen
Die Funktionen, die an setInterval() übergeben werden, laufen mit den normalen Funktionsaufruf-Semantiken ab, um die Referenz von this zu bestimmen.
Dieses Problem wird im JavaScript-Referenz detailliert erklärt.
Für Nicht-Pfeil-Funktionen wird der this-Kontext auf das globalThis (ein Alias für window in Browsern) Objekt gesetzt.
Das folgende Beispiel demonstriert, wie dies zu unerwartetem Verhalten führen 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 Funktion, die an setInterval übergeben wird, den korrekten this-Kontext hat. Es gibt drei Hauptmethoden, dies zu erreichen:
-
Wenn Sie den
this-Kontext explizit spezifizieren möchten, anstelle die Methode direkt zu übergeben, wickeln Sie den Methodenaufruf in eine andere anonyme Funktion, die die Methode mit dem korrekten Kontext explizit aufruft:jssetInterval(() => counter.count("bar"), 1000); setInterval(function () { counter.count("bar"); }, 1000); -
Wenn Sie den
this-Kontext des Codes, dersetInterval()aufruft, verwenden möchten, sollten Sie immer eine Pfeilfunktion nutzen, die denthis-Kontext ihres umgebenden Scopes 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 (die den Speicherverbrauch erhöhen) vermeiden möchten, während Sie den
this-Kontext explizit spezifizieren, 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 auszuführen, die im code-Parameter übergeben werden.
Wenn die Eingabe eine potenziell unsichere Zeichenfolge ist, die von einem Benutzer bereitgestellt wird, stellt dies einen möglichen Vektor für Cross-Site-Scripting (XSS) Angriffe dar.
Zum Beispiel zeigt der folgende Code, wie setInterval() möglicherweise untrustedCode ausführt, das von einem Benutzer bereitgestellt wurde:
const untrustedCode = "alert('Potentially evil code!');";
const id = setInterval(untrustedCode, 1000);
Webseiten mit einer Content Security Policy (CSP), die script-src oder default-src spezifizieren, verhindern standardmäßig das Ausführen eines solchen Codes.
Sie können unsafe-eval in Ihrer CSP angeben, um setInterval() die Ausführung zu erlauben, aber das ist unsicher, da es einen der Hauptschutzmechanismen von CSP deaktiviert.
Siehe Inline JavaScript im CSP-Leitfaden.
Wenn Sie die Skripte über setInterval() ausführen müssen, können Sie diese Probleme mindern, indem Sie immer TrustedScript Objekte anstelle von Zeichenfolgen zuweisen und vertrauenswürdige Typen durchsetzen mit 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 Schlüsselwort in Ihrer CSP script-src Direktive angeben.
Dies funktioniert auf die gleiche Weise wie unsafe-eval, erlaubt jedoch nur die Methode zur Ausführung, wenn vertrauenswürdige Typen aktiviert sind (wenn Sie unsafe-eval verwenden, würde es die Ausführung auch in Browsern erlauben, die keine vertrauenswürdigen Typen unterstützen).
Zum Beispiel, könnte die erforderliche CSP für Ihre Seite so 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 benutzerdefiniertes Skript erfordert. Wenn möglich, sollten Sie die erlaubten Skripte auf den genaujenigen Code beschränken, den Sie für vertrauenswürdig halten. Wenn das nicht möglich ist, könnten Sie die Verwendung bestimmter Funktionen innerhalb der bereitgestellten Zeichenfolge zulassen oder blockieren.
Beispiele
Beachten Sie, dass diese Beispiele der Kürze halber keine vertrauenswürdigen Typen verwenden.
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: Zwei Farben alternieren
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> |