EventTarget: Methode addEventListener()
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2021.
Hinweis: Dieses Feature ist verfügbar in Web Workers.
Die addEventListener()
-Methode der EventTarget
-Schnittstelle richtet eine Funktion ein, die immer dann aufgerufen wird, wenn das angegebene Ereignis an das Ziel zugestellt wird.
Häufige Ziele sind Element
oder dessen Kinder, Document
und Window
, aber das Ziel kann jedes Objekt sein, das Ereignisse unterstützt (wie z.B. IDBRequest
).
Hinweis: Die addEventListener()
-Methode ist der empfohlene Weg, um einen Ereignis-Listener zu registrieren. Die Vorteile sind wie folgt:
- Sie ermöglicht das Hinzufügen von mehr als einem Handler für ein Ereignis. Dies ist besonders nützlich für Bibliotheken, JavaScript-Module oder jede andere Art von Code, der gut mit anderen Bibliotheken oder Erweiterungen funktionieren muss.
- Im Gegensatz zur Verwendung einer
onXYZ
-Eigenschaft bietet sie eine feinere Kontrolle darüber, in welcher Phase der Listener aktiviert wird (Erfassung vs. Blasen). - Sie funktioniert bei jedem Ereignisziel, nicht nur bei HTML- oder SVG-Elementen.
Die Methode addEventListener()
funktioniert, indem sie eine Funktion oder ein Objekt, das eine handleEvent()
-Funktion implementiert, zur Liste der Ereignis-Listener für den angegebenen Ereignistyp auf dem EventTarget
, auf dem sie aufgerufen wird, hinzufügt. Wenn die Funktion oder das Objekt bereits in der Liste der Ereignis-Listener für dieses Ziel vorhanden ist, wird die Funktion oder das Objekt nicht ein zweites Mal hinzugefügt.
Hinweis: Wenn eine bestimmte anonyme Funktion in der Liste der für ein bestimmtes Ziel registrierten Ereignis-Listener enthalten ist und später im Code eine identische anonyme Funktion in einem addEventListener
-Aufruf übergeben wird, wird die zweite Funktion ebenfalls zur Liste der Ereignis-Listener für dieses Ziel hinzugefügt.
Tatsächlich sind anonyme Funktionen nicht identisch, auch wenn sie mit demselben unveränderten Quellcode wiederholt definiert werden, sogar in einer Schleife.
Wiederholt dieselbe unbenannte Funktion in solchen Fällen zu definieren, kann problematisch sein. (Siehe Speicherprobleme unten.)
Wenn ein Ereignis-Listener während der Verarbeitung des Ereignisses zu einem EventTarget
hinzugefügt wird - das heißt innerhalb eines anderen Listeners - wird das Ereignis den neuen Listener nicht auslösen. Der neue Listener kann jedoch während einer späteren Phase des Ereignisflusses ausgelöst werden, z. B. während der Blasenphase.
Syntax
addEventListener(type, listener)
addEventListener(type, listener, options)
addEventListener(type, listener, useCapture)
Parameter
type
-
Ein Groß- und Kleinschreibung berücksichtigender String, der den zu hörenden Ereignistyp darstellt.
listener
-
Das Objekt, das eine Benachrichtigung erhält (ein Objekt, das die
Event
-Schnittstelle implementiert), wenn ein Ereignis des angegebenen Typs auftritt. Dies mussnull
, ein Objekt mit einerhandleEvent()
-Methode oder eine JavaScript-Funktion sein. Siehe Der Callback des Ereignis-Listeners für Details zum Callback selbst. options
Optional-
Ein Objekt, das Eigenschaften über den Ereignis-Listener angibt. Die verfügbaren Optionen sind:
capture
Optional-
Ein boolescher Wert, der angibt, dass Ereignisse dieses Typs an die registrierte
listener
gesendet werden, bevor sie an ein darunterliegendesEventTarget
im DOM-Baum gesendet werden. Wenn nicht angegeben, ist der Standardwertfalse
. once
Optional-
Ein boolescher Wert, der angibt, dass der
listener
höchstens einmal nach dem Hinzufügen aufgerufen werden sollte. Wenntrue
, wird derlistener
automatisch entfernt, wenn er aufgerufen wird. Wenn nicht angegeben, ist der Standardwertfalse
. passive
Optional-
Ein boolescher Wert, der, falls
true
, angibt, dass die vomlistener
angegebene Funktion niemalspreventDefault()
aufrufen wird. Wenn ein passiver ListenerpreventDefault()
aufruft, wird nichts passieren und es kann eine Konsolenwarnung generiert werden.Wenn diese Option nicht angegeben wird, ist der Standardwert
false
– außer in anderen Browsern als Safari, wo der Standardwert fürwheel
,mousewheel
,touchstart
undtouchmove
Ereignisse auf Dokument-Ebenetrue
ist. Siehe Verwendung passiver Listener für mehr Informationen. signal
Optional-
Ein
AbortSignal
. Der Listener wird entfernt, wenn dieabort()
-Methode des angegebenenAbortSignal
-Objekts aufgerufen wird. Wenn nicht angegeben, ist keinAbortSignal
mit dem Listener verknüpft.
useCapture
Optional-
Ein boolescher Wert, der angibt, ob Ereignisse dieses Typs gesendet werden, um den registrierten
listener
bevor er an ein darunterliegendesEventTarget
im DOM-Baum gesendet wird. Ereignisse, die den Baum nach oben durchlaufen, lösen keinen Listener aus, der für die Verwendung von Erfassung bestimmt ist. Ereignis-Blasen und Erfassung sind zwei Methoden der Ereignisausbreitung, die in einem Element auftreten, das in ein anderes Element eingebettet ist, wenn beide Elemente einen Handler für dieses Ereignis registriert haben. Der Modus der Ereignisausbreitung bestimmt die Reihenfolge, in der die Elemente das Ereignis erhalten. Siehe DOM Level 3 Events und JavaScript-Ereignisreihenfolge für eine detaillierte Erklärung. Wenn nicht angegeben, ist der Standardwert vonuseCapture
false
.Hinweis: Für Ereignis-Listener, die an das Ereignisziel angehängt sind, befindet sich das Ereignis in der Zielphase, anstatt in den Erfassungs- und Blasenphasen. Ereignis-Listener in der Erfassungs Phase werden vor Ereignis-Listenern in den Ziel- und Blasenphasen aufgerufen.
wantsUntrusted
Optional Nicht standardisiert-
Ein Firefox (Gecko)-spezifischer Parameter. Wenn
true
, erhält der Listener synthetische Ereignisse von Webinhalten (der Standardwert istfalse
für die Browser-chrome undtrue
für reguläre Webseiten). Dieser Parameter ist nützlich für Code in Add-ons sowie im Browser selbst.
Rückgabewert
Keiner (undefined
).
Anwendungshinweise
Der Callback des Ereignis-Listeners
Der Ereignis-Listener kann entweder als Callback-Funktion oder als Objekt angegeben werden, dessen handleEvent()
-Methode als Callback-Funktion dient.
Die Callback-Funktion selbst hat die gleichen Parameter und den gleichen Rückgabewert wie die handleEvent()
-Methode; das heißt, der Callback akzeptiert einen einzelnen Parameter: ein auf Event
basierendes Objekt, das das aufgetretene Ereignis beschreibt, und es gibt nichts zurück.
Zum Beispiel könnte ein Event-Handler-Callback, der sowohl fullscreenchange
als auch fullscreenerror
behandeln kann, so aussehen:
function handleEvent(event) {
if (event.type === "fullscreenchange") {
/* handle a full screen toggle */
} else {
/* handle a full screen toggle error */
}
}
Der Wert von "this" innerhalb des Handlers
Es ist oft wünschenswert, auf das Element zu verweisen, auf dem der Ereignis-Handler ausgelöst wurde, z.B. wenn ein generischer Handler für eine Gruppe ähnlicher Elemente verwendet wird.
Wenn eine Handler-Funktion einem Element mit addEventListener()
hinzugefügt wird, ist der Wert von this
innerhalb des Handlers ein Verweis auf das Element. Es wird derselbe Wert wie die currentTarget
-Eigenschaft des Ereignis-Arguments, das an den Handler übergeben wird.
my_element.addEventListener("click", function (e) {
console.log(this.className); // logs the className of my_element
console.log(e.currentTarget === this); // logs `true`
});
Zur Erinnerung: Pfeilfunktionen haben keinen eigenen this
-Kontext.
my_element.addEventListener("click", (e) => {
console.log(this.className); // WARNING: `this` is not `my_element`
console.log(e.currentTarget === this); // logs `false`
});
Wenn ein Ereignis-Handler (z.B. onclick
) auf einem Element im HTML-Quellcode angegeben wird, wird der JavaScript-Code im Attributwert effektiv in einer Handler-Funktion umschlossen, die den Wert von this
in einer Weise bindet, die mit addEventListener()
konsistent ist; ein Vorkommen von this
im Code stellt einen Verweis auf das Element dar.
<table id="my_table" onclick="console.log(this.id);">
<!-- `this` refers to the table; logs 'my_table' -->
…
</table>
Beachten Sie, dass der Wert von this
innerhalb einer Funktion, die vom Code im Attributwert aufgerufen wird, sich gemäß den Standardregeln verhält. Dies wird im folgenden Beispiel gezeigt:
<script>
function logID() {
console.log(this.id);
}
</script>
<table id="my_table" onclick="logID();">
<!-- when called, `this` will refer to the global object -->
…
</table>
Der Wert von this
innerhalb von logID()
ist ein Verweis auf das globale Objekt Window
(oder undefined
im Fall des strengen Modus).
"this" mit bind() festlegen
Die Methode Function.prototype.bind()
ermöglicht es Ihnen, einen festen this
-Kontext für alle nachfolgenden Aufrufe zu etablieren — wodurch Probleme umgangen werden, bei denen unklar ist, was this
sein wird, abhängig vom Kontext, aus dem Ihre Funktion aufgerufen wurde. Beachten Sie jedoch, dass Sie einen Verweis auf den Listener speichern müssen, damit Sie ihn später entfernen können.
Dies ist ein Beispiel mit und ohne bind()
:
class Something {
name = "Something Good";
constructor(element) {
// bind causes a fixed `this` context to be assigned to `onclick2`
this.onclick2 = this.onclick2.bind(this);
element.addEventListener("click", this.onclick1, false);
element.addEventListener("click", this.onclick2, false); // Trick
}
onclick1(event) {
console.log(this.name); // undefined, as `this` is the element
}
onclick2(event) {
console.log(this.name); // 'Something Good', as `this` is bound to the Something instance
}
}
const s = new Something(document.body);
Eine weitere Lösung ist die Verwendung einer speziellen Funktion namens handleEvent()
, um alle Ereignisse abzufangen:
class Something {
name = "Something Good";
constructor(element) {
// Note that the listeners in this case are `this`, not this.handleEvent
element.addEventListener("click", this, false);
element.addEventListener("dblclick", this, false);
}
handleEvent(event) {
console.log(this.name); // 'Something Good', as this is bound to newly created object
switch (event.type) {
case "click":
// some code here…
break;
case "dblclick":
// some code here…
break;
}
}
}
const s = new Something(document.body);
Eine andere Möglichkeit, den Verweis auf this
zu handhaben, ist die Verwendung einer Pfeilfunktion, die keinen separaten this
-Kontext erstellt.
class SomeClass {
name = "Something Good";
register() {
window.addEventListener("keydown", (e) => {
this.someMethod(e);
});
}
someMethod(e) {
console.log(this.name);
switch (e.code) {
case "ArrowUp":
// some code here…
break;
case "ArrowDown":
// some code here…
break;
}
}
}
const myObject = new SomeClass();
myObject.register();
Daten in einen und aus einem Ereignis-Listener übertragen
Ereignis-Listener nehmen nur ein Argument an, ein Event
oder eine Unterklasse von Event
, das automatisch an den Listener übergeben wird, und der Rückgabewert wird ignoriert. Daher müssen Sie, um Daten in einen und aus einem Ereignis-Listener zu übertragen, Closures erstellen, anstatt die Daten durch Parameter und Rückgabewerte zu übergeben.
Die als Event-Listener übergebenen Funktionen haben Zugriff auf alle in den äußeren Bereichen deklarierten Variablen, die die Funktion umschließen.
const myButton = document.getElementById("my-button-id");
let someString = "Data";
myButton.addEventListener("click", () => {
console.log(someString);
// 'Data' on first click,
// 'Data Again' on second click
someString = "Data Again";
});
console.log(someString); // Expected Value: 'Data' (will never output 'Data Again')
Lesen Sie den Funktionsleitfaden für weitere Informationen über Funktionsbereiche.
Speicherprobleme
const elts = document.getElementsByTagName("*");
// Case 1
for (const elt of elts) {
elt.addEventListener(
"click",
(e) => {
// Do something
},
false,
);
}
// Case 2
function processEvent(e) {
// Do something
}
for (const elt of elts) {
elt.addEventListener("click", processEvent, false);
}
Im ersten Fall oben wird mit jeder Iteration der Schleife eine neue (anonyme) Handlerfunktion erstellt. Im zweiten Fall wird dieselbe vorher deklarierte Funktion als Ereignis-Handler verwendet, was zu einem geringeren Speicherverbrauch führt, da nur eine Handler-Funktion erstellt wird. Zudem ist es im ersten Fall nicht möglich, removeEventListener()
aufzurufen, da kein Verweis auf die anonyme Funktion gespeichert wird (oder hier auf keine der möglicherweise durch die Schleife erstellten anonymen Funktionen). Im zweiten Fall ist es möglich, myElement.removeEventListener("click", processEvent, false)
auszuführen, da processEvent
der Funktionsverweis ist.
Bezüglich des Speicherverbrauchs ist eigentlich nicht das Fehlen eines Funktionsverweises das reale Problem, sondern das Fehlen eines statischen Funktionsverweises.
Verwendung passiver Listener
Wenn ein Ereignis eine Standardaktion hat — z.B. ein wheel
-Ereignis, das standardmäßig den Container scrollt — ist der Browser im Allgemeinen nicht in der Lage, die Standardaktion zu starten, bis der Ereignis-Listener beendet ist, da er nicht im Voraus weiß, ob der Ereignis-Listener die Standardaktion durch Aufruf von Event.preventDefault()
abbrechen könnte. Wenn der Ereignis-Listener zu lange benötigt, um ausgeführt zu werden, kann dies zu einer spürbaren Verzögerung führen, auch bekannt als Jank, bevor die Standardaktion ausgeführt werden kann.
Durch das Setzen der passive
-Option auf true
erklärt ein Ereignis-Listener, dass er die Standardaktion nicht abbrechen wird, sodass der Browser die Standardaktion sofort starten kann, ohne darauf zu warten, dass der Listener fertig ist. Wenn der Listener dann Event.preventDefault()
aufruft, hat dies keine Auswirkungen.
Die Spezifikation für addEventListener()
definiert den Standardwert für die passive
-Option immer als false
. Um jedoch die Scroll-Leistungsverbesserungen durch passive Listener im Legacy-Code zu realisieren, haben moderne Browser den Standardwert der passive
-Option für die wheel
, mousewheel
, touchstart
und touchmove
Ereignisse auf den Dokument-Ebene-Knoten Window
, Document
und Document.body
geändert. Das verhindert, dass der Ereignis-Listener das Ereignis abbricht, sodass er das Seitenrendering während des Scrolling des Benutzers nicht blockieren kann.
Deshalb, wenn Sie dieses Verhalten überschreiben und sicherstellen möchten, dass die passive
-Option false
ist, müssen Sie die Option explizit auf false
setzen (anstatt sich auf den Standardwert zu verlassen).
Sie müssen sich keine Sorgen über den Wert von passive
für das grundlegende scroll
-Ereignis machen. Da es nicht abgebrochen werden kann, können Ereignis-Listener das Seitenrendering nicht blockieren.
Siehe Verbesserung der Scroll-Leistung durch passive Listener für ein Beispiel, das die Wirkung passiver Listener zeigt.
Beispiele
Einfachen Listener hinzufügen
Dieses Beispiel zeigt, wie addEventListener()
verwendet wird, um auf Mausklicks auf ein Element zu achten.
HTML
<table id="outside">
<tr>
<td id="t1">one</td>
</tr>
<tr>
<td id="t2">two</td>
</tr>
</table>
JavaScript
// Function to change the content of t2
function modifyText() {
const t2 = document.getElementById("t2");
const isNodeThree = t2.firstChild.nodeValue === "three";
t2.firstChild.nodeValue = isNodeThree ? "two" : "three";
}
// Add event listener to table
const el = document.getElementById("outside");
el.addEventListener("click", modifyText, false);
In diesem Code ist modifyText()
ein Listener für click
-Ereignisse, der mit addEventListener()
registriert wurde. Ein Klick irgendwo in der Tabelle wird an den Handler weitergeleitet und führt modifyText()
aus.
Ergebnis
Abbrechbaren Listener hinzufügen
Dieses Beispiel zeigt, wie ein addEventListener()
hinzugefügt wird, das mit einem AbortSignal
abgebrochen werden kann.
HTML
<table id="outside">
<tr>
<td id="t1">one</td>
</tr>
<tr>
<td id="t2">two</td>
</tr>
</table>
JavaScript
// Add an abortable event listener to table
const controller = new AbortController();
const el = document.getElementById("outside");
el.addEventListener("click", modifyText, { signal: controller.signal });
// Function to change the content of t2
function modifyText() {
const t2 = document.getElementById("t2");
if (t2.firstChild.nodeValue === "three") {
t2.firstChild.nodeValue = "two";
} else {
t2.firstChild.nodeValue = "three";
controller.abort(); // remove listener after value reaches "three"
}
}
Im obigen Beispiel modifizieren wir den Code aus dem vorherigen Beispiel so, dass nach dem Ändern des Inhalts der zweiten Zeile auf "drei" abort()
vom AbortController
aufgerufen wird, den wir an den addEventListener()
-Aufruf übergeben haben. Das führt dazu, dass der Wert für immer "drei" bleibt, da wir keinen Code mehr haben, der auf ein Klick-Ereignis hört.
Ergebnis
Ereignis-Listener mit anonymer Funktion
Hier werden wir uns ansehen, wie eine anonyme Funktion verwendet wird, um Parameter an den Ereignis-Listener zu übergeben.
HTML
<table id="outside">
<tr>
<td id="t1">one</td>
</tr>
<tr>
<td id="t2">two</td>
</tr>
</table>
JavaScript
// Function to change the content of t2
function modifyText(new_text) {
const t2 = document.getElementById("t2");
t2.firstChild.nodeValue = new_text;
}
// Function to add event listener to table
const el = document.getElementById("outside");
el.addEventListener(
"click",
function () {
modifyText("four");
},
false,
);
Beachten Sie, dass der Listener eine anonyme Funktion ist, die Code kapselt, der dann wiederum Parameter an die modifyText()
-Funktion senden kann, die für die eigentliche Reaktion auf das Ereignis verantwortlich ist.
Ergebnis
Ereignis-Listener mit einer Pfeilfunktion
Dieses Beispiel zeigt einen einfachen Ereignis-Listener, der mit Notation der Pfeilfunktion implementiert ist.
HTML
<table id="outside">
<tr>
<td id="t1">one</td>
</tr>
<tr>
<td id="t2">two</td>
</tr>
</table>
JavaScript
// Function to change the content of t2
function modifyText(new_text) {
const t2 = document.getElementById("t2");
t2.firstChild.nodeValue = new_text;
}
// Add event listener to table with an arrow function
const el = document.getElementById("outside");
el.addEventListener(
"click",
() => {
modifyText("four");
},
false,
);
Ergebnis
Bitte beachten Sie, dass, während anonyme und Pfeilfunktionen ähnlich sind, sie unterschiedliche this
-Bindings haben. Während anonyme (und alle traditionellen JavaScript-Funktionen) ihre eigenen this
-Bindings erstellen, erben Pfeilfunktionen das this
-Binding der enthaltenden Funktion.
Das bedeutet, dass die Variablen und Konstanten, die der enthaltenden Funktion zur Verfügung stehen, auch dem Ereignis-Handler zur Verfügung stehen, wenn eine Pfeilfunktion verwendet wird.
Beispiel für die Verwendung von Optionen
HTML
<div class="outer">
outer, once & none-once
<div class="middle" target="_blank">
middle, capture & none-capture
<a class="inner1" href="https://www.mozilla.org" target="_blank">
inner1, passive & preventDefault(which is not allowed)
</a>
<a class="inner2" href="https://developer.mozilla.org/" target="_blank">
inner2, none-passive & preventDefault(not open new page)
</a>
</div>
</div>
<hr />
<button class="clear-button">Clear logs</button>
<section class="demo-logs"></section>
CSS
.outer,
.middle,
.inner1,
.inner2 {
display: block;
width: 520px;
padding: 15px;
margin: 15px;
text-decoration: none;
}
.outer {
border: 1px solid red;
color: red;
}
.middle {
border: 1px solid green;
color: green;
width: 460px;
}
.inner1,
.inner2 {
border: 1px solid purple;
color: purple;
width: 400px;
}
JavaScript
const outer = document.querySelector(".outer");
const middle = document.querySelector(".middle");
const inner1 = document.querySelector(".inner1");
const inner2 = document.querySelector(".inner2");
const capture = {
capture: true,
};
const noneCapture = {
capture: false,
};
const once = {
once: true,
};
const noneOnce = {
once: false,
};
const passive = {
passive: true,
};
const nonePassive = {
passive: false,
};
outer.addEventListener("click", onceHandler, once);
outer.addEventListener("click", noneOnceHandler, noneOnce);
middle.addEventListener("click", captureHandler, capture);
middle.addEventListener("click", noneCaptureHandler, noneCapture);
inner1.addEventListener("click", passiveHandler, passive);
inner2.addEventListener("click", nonePassiveHandler, nonePassive);
function onceHandler(event) {
log("outer, once");
}
function noneOnceHandler(event) {
log("outer, none-once, default\n");
}
function captureHandler(event) {
//event.stopImmediatePropagation();
log("middle, capture");
}
function noneCaptureHandler(event) {
log("middle, none-capture, default");
}
function passiveHandler(event) {
// Unable to preventDefault inside passive event listener invocation.
event.preventDefault();
log("inner1, passive, open new page");
}
function nonePassiveHandler(event) {
event.preventDefault();
//event.stopPropagation();
log("inner2, none-passive, default, not open new page");
}
Ergebnis
Klicken Sie nacheinander auf die äußeren, mittleren, inneren Container, um zu sehen, wie die Optionen funktionieren.
Ereignis-Listener mit mehreren Optionen
Sie können mehr als eine der Optionen im options
-Parameter einstellen. Im folgenden Beispiel setzen wir zwei Optionen:
passive
, um zu bestätigen, dass der Handler nichtpreventDefault()
aufrufen wird.once
, um sicherzustellen, dass der Ereignis-Handler nur einmal aufgerufen wird.
HTML
<button id="example-button">You have not clicked this button.</button>
<button id="reset-button">Click this button to reset the first button.</button>
JavaScript
const buttonToBeClicked = document.getElementById("example-button");
const resetButton = document.getElementById("reset-button");
// the text that the button is initialized with
const initialText = buttonToBeClicked.textContent;
// the text that the button contains after being clicked
const clickedText = "You have clicked this button.";
// we hoist the event listener callback function
// to prevent having duplicate listeners attached
function eventListener() {
buttonToBeClicked.textContent = clickedText;
}
function addListener() {
buttonToBeClicked.addEventListener("click", eventListener, {
passive: true,
once: true,
});
}
// when the reset button is clicked, the example button is reset,
// and allowed to have its state updated again
resetButton.addEventListener("click", () => {
buttonToBeClicked.textContent = initialText;
addListener();
});
addListener();
Ergebnis
Verbesserung der Scroll-Leistung durch passive Listener
Das folgende Beispiel zeigt den Effekt der Einstellung von passive
. Es enthält ein <div>
, das etwas Text und ein Kontrollkästchen enthält.
HTML
<div id="container">
<p>
But down there it would be dark now, and not the lovely lighted aquarium she
imagined it to be during the daylight hours, eddying with schools of tiny,
delicate animals floating and dancing slowly to their own serene currents
and creating the look of a living painting. That was wrong, in any case. The
ocean was different from an aquarium, which was an artificial environment.
The ocean was a world. And a world is not art. Dorothy thought about the
living things that moved in that world: large, ruthless and hungry. Like us
up here.
</p>
</div>
<div>
<input type="checkbox" id="passive" name="passive" checked />
<label for="passive">passive</label>
</div>
JavaScript
Der Code fügt einen Listener für das wheel
-Ereignis des Containers hinzu, das standardmäßig den Container scrollt. Der Listener führt eine langlaufende Operation aus. Zunächst wird der Listener mit der passive
-Option hinzugefügt, und wann immer das Kontrollkästchen umgeschaltet wird, schaltet der Code die passive
-Option um.
const passive = document.querySelector("#passive");
passive.addEventListener("change", (event) => {
container.removeEventListener("wheel", wheelHandler);
container.addEventListener("wheel", wheelHandler, {
passive: passive.checked,
once: true,
});
});
const container = document.querySelector("#container");
container.addEventListener("wheel", wheelHandler, {
passive: true,
once: true,
});
function wheelHandler() {
function isPrime(n) {
for (let c = 2; c <= Math.sqrt(n); ++c) {
if (n % c === 0) {
return false;
}
}
return true;
}
const quota = 1000000;
const primes = [];
const maximum = 1000000;
while (primes.length < quota) {
const candidate = Math.floor(Math.random() * (maximum + 1));
if (isPrime(candidate)) {
primes.push(candidate);
}
}
console.log(primes);
}
Ergebnis
Der Effekt ist, dass:
- Zunächst ist der Listener passiv, daher erfolgt das Scrollen des Containers mit dem Rad sofort.
- Wenn Sie "passive" deaktivieren und versuchen, den Container mit dem Rad zu scrollen, gibt es eine spürbare Verzögerung, bevor der Container scrollt, da der Browser warten muss, bis der langlaufende Listener beendet ist.
Spezifikationen
Specification |
---|
DOM Standard # ref-for-dom-eventtarget-addeventlistener③ |
Browser-Kompatibilität
BCD tables only load in the browser