EventTarget: addEventListener()-Methode
Baseline Widely available *
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
* Some parts of this feature may have varying levels of support.
Hinweis: Diese Funktion ist in Web Workers verfügbar.
Die addEventListener()
-Methode der EventTarget
-Schnittstelle
richtet eine Funktion ein, die immer dann aufgerufen wird, wenn das angegebene Ereignis an das Ziel gesendet wird.
Typische Ziele sind Element
oder dessen Kinder, Document
und Window
, aber das Ziel kann jedes Objekt sein, das Ereignisse unterstützt (wie zum Beispiel IDBRequest
).
Hinweis:
Die addEventListener()
-Methode ist der empfohlene Weg, um einen Ereignis-Listener zu registrieren. Die Vorteile sind folgende:
- Es erlaubt das Hinzufügen von mehr als einem Handler für ein Ereignis. Dies ist besonders nützlich für Bibliotheken, JavaScript-Module oder jede Art von Code, die gut mit anderen Bibliotheken oder Erweiterungen funktionieren muss.
- Im Gegensatz zur Verwendung einer
onXYZ
-Eigenschaft bietet es eine feinere Steuerung der Phase, in der der Listener aktiviert wird (Capturing vs. Bubbling). - Es funktioniert auf jedem Ereignisziel, nicht nur auf HTML- oder SVG-Elementen.
Die Methode addEventListener()
funktioniert, indem sie eine Funktion oder ein Objekt, das eine handleEvent()
-Funktion implementiert, zur Liste der Event-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 Event-Listener für dieses Ziel enthalten 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 Event-Listener enthalten ist und später im Code eine identische anonyme Funktion in einem addEventListener
-Aufruf übergeben wird, wird die zweite Funktion auch zur Liste der Event-Listener für dieses Ziel hinzugefügt.
Tatsächlich sind anonyme Funktionen nicht identisch, selbst wenn sie denselben unveränderten Quellcode verwenden, der wiederholt aufgerufen wird, sogar in einer Schleife.
Die wiederholte Definition derselben unbenannten Funktion in solchen Fällen kann problematisch sein. (Siehe Speicherprobleme, unten.)
Wenn ein Event-Listener während der Verarbeitung des Ereignisses von einem anderen Listener zu einem EventTarget
hinzugefügt wird, löst dieses Ereignis den neuen Listener nicht aus.
Der neue Listener kann jedoch in einer späteren Phase des Ereignisflusses ausgelöst werden, beispielsweise während der Bubbling-Phase.
Syntax
addEventListener(type, listener)
addEventListener(type, listener, options)
addEventListener(type, listener, useCapture)
Parameters
type
-
Eine groß-/kleinschreibungsabhängige Zeichenkette, die den Ereignistyp darstellt, auf den gelauscht werden soll.
listener
-
Das Objekt, das bei Auftreten eines Ereignisses des angegebenen Typs eine Benachrichtigung erhält (ein Objekt, das die
Event
-Schnittstelle implementiert). Dies mussnull
, ein Objekt mit einerhandleEvent()
-Methode oder eine JavaScript-Funktion sein. Siehe Der Event-Listener-Callback für Details zum Callback selbst. options
Optional-
Ein Objekt, das Eigenschaften über den Event-Listener spezifiziert. Die verfügbaren Optionen sind:
capture
Optional-
Ein Boolean-Wert, der angibt, dass Ereignisse dieses Typs an den registrierten
listener
gesendet werden, bevor sie an ein darunterliegendesEventTarget
im DOM-Baum gesendet werden. Wenn nicht angegeben, ist der Standardwertfalse
. once
Optional-
Ein Boolean-Wert, der angibt, dass der
listener
höchstens einmal aufgerufen werden soll, nachdem er hinzugefügt wurde. Wenntrue
, wird derlistener
automatisch entfernt, wenn er aufgerufen wird. Wenn nicht angegeben, ist der Standardwertfalse
. passive
Optional-
Ein Boolean-Wert, der, wenn
true
, anzeigt, dass die vonlistener
angegebene Funktion niemalspreventDefault()
aufrufen wird. Wenn ein passiver ListenerpreventDefault()
aufruft, passiert nichts und es kann eine Konsolenwarnung generiert werden.Wenn diese Option nicht angegeben ist, ist der Standardwert
false
– außer in Browsern außer Safari, wo sie fürwheel
,mousewheel
,touchstart
undtouchmove
Ereignisse auftrue
gesetzt ist. Lesen Sie Verwendung passiver Listener, um mehr zu erfahren. signal
Optional-
Ein
AbortSignal
. Der Listener wird entfernt, wenn dieabort()
-Methode desAbortController
, dem dasAbortSignal
gehört, aufgerufen wird. Wenn nicht angegeben, wird keinAbortSignal
mit dem Listener verknüpft.
useCapture
Optional-
Ein Boolean-Wert, der angibt, ob Ereignisse dieses Typs an den registrierten
listener
vor den anderenEventTarget
-Elementen, die darunter im DOM-Baum liegen, gesendet werden. Ereignisse, die auf dem Weg nach oben durch den Baum blasen, lösen keinen Listener aus, der für die Verwendung von Capturing gekennzeichnet ist. Event-Bubbling und Capturing sind zwei Möglichkeiten zur Verteilung von Ereignissen, die in einem verschachtelten Element auftreten, wenn beide Elemente einen Handler für dieses Ereignis registriert haben. Der Modus der Ereignisverteilung bestimmt die Reihenfolge, in der Elemente das Ereignis erhalten. Siehe die DOM-Spezifikation und JavaScript-Ereignisreihenfolge für eine detaillierte Erklärung. Wenn nicht angegeben, istuseCapture
standardmäßigfalse
.Hinweis: Für Event-Listener, die an das Ereignisziel angehängt sind, befindet sich das Ereignis in der Zielphase, anstatt in den Capturing- und Bubbling-Phasen. Event-Listener in der Capturing-Phase werden vor Event-Listenern in der Ziel- und Bubbling-Phase aufgerufen.
wantsUntrusted
Optional Nicht standardisiert-
Ein Firefox (Gecko)-spezifischer Parameter. Wenn
true
, empfängt der Listener synthetische Ereignisse, die von Webinhalten gesendet werden (der Standardwert istfalse
für Browser-Chrome undtrue
für reguläre Webseiten). Dieser Parameter ist nützlich für Code, der in Add-Ons sowie im Browser selbst gefunden wird.
Rückgabewert
Keine (undefined
).
Nutzungshinweise
Der Event-Listener-Callback
Der Event-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.
Beispielsweise könnte ein Ereignishandler-Callback, das sowohl fullscreenchange
als auch fullscreenerror
behandeln kann, folgendermaßen 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 Ereignishandler ausgelöst wurde, zum Beispiel bei der Verwendung eines generischen Handlers für eine Gruppe ähnlicher Elemente.
Wenn eine Handler-Funktion mit addEventListener()
an ein Element angehängt wird, ist der Wert von this
innerhalb des Handlers eine Referenz auf das Element. Es wird der gleiche Wert wie die currentTarget
-Eigenschaft des Ereignisarguments sein, 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: Arrow-Funktionen 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 Ereignishandler (zum Beispiel onclick
) in der HTML-Quelle für ein Element angegeben wird, wird der JavaScript-Code im Attributwert effektiv in eine Handler-Funktion eingeschlossen, die den Wert von this
auf eine Weise bindet, die mit der addEventListener()
-Methode konsistent ist; ein Vorkommen von this
im Code stellt eine Referenz zum 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, gemäß den Standardregeln funktioniert. 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 eine Referenz auf das globale Objekt Window
(oder undefined
im Fall des Strict Mode).
"this" mithilfe von bind() spezifizieren
Die Function.prototype.bind()
-Methode ermöglicht es Ihnen, einen festen this
-Kontext für alle nachfolgenden Aufrufe festzulegen – um Probleme zu vermeiden, bei denen nicht klar ist, was this
sein wird, abhängig vom Kontext, aus dem Ihre Funktion aufgerufen wurde. Beachten Sie jedoch, dass Sie eine Referenz auf den Listener aufbewahren 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 andere Lösung ist die Verwendung einer speziellen Funktion namens handleEvent()
, um beliebige 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 weitere Möglichkeit, den Bezug zu this
zu handhaben, ist die Verwendung einer Arrow-Funktion, 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 Event-Listener hinein- und herausbekommen
Event-Listener akzeptieren nur ein Argument, 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 Event-Listener zu bekommen, anstelle der Übergabe von Daten durch Parameter und Rückgabewerte Closures erstellen.
Die als Event-Listener übergebenen Funktionen haben Zugriff auf alle in den äußeren Ebenen enthaltenen 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 elems = document.getElementsByTagName("*");
// Case 1
for (const elem of elems) {
elem.addEventListener(
"click",
(e) => {
// Do something
},
false,
);
}
// Case 2
function processEvent(e) {
// Do something
}
for (const elem of elems) {
elem.addEventListener("click", processEvent, false);
}
Im ersten oben gezeigten Fall wird mit jeder Iteration der Schleife eine neue (anonyme) Handler-Funktion erstellt. Im zweiten Fall wird dieselbe vorher deklarierte Funktion als Event-Handler verwendet, was zu einem geringeren Speicherverbrauch führt, da nur eine Handler-Funktion erstellt wird. Außerdem ist es im ersten Fall nicht möglich, removeEventListener()
aufzurufen, da keine Referenz auf die anonyme Funktion behalten wird (oder hier auf keine der möglicherweise durch die Schleife erstellten mehrfachen anonymen Funktionen). Im zweiten Fall ist es möglich, myElement.removeEventListener("click", processEvent, false)
zu verwenden, da processEvent
die Funktionsreferenz ist.
Tatsächlich ist in Bezug auf den Speicherverbrauch nicht das Nichtbehalten einer Funktionsreferenz das eigentliche Problem, sondern das Nichtbehalten einer statischen Funktionsreferenz.
Verwendung passiver Listener
Wenn ein Ereignis eine Standardaktion hat – zum Beispiel ein wheel
-Ereignis, das das Container-Scrollen standardmäßig auslöst – ist der Browser im Allgemeinen nicht in der Lage, die Standardaktion zu starten, bis der Ereignis-Listener abgeschlossen ist, da er im Voraus nicht weiß, ob der Ereignis-Listener die Standardaktion durch Aufrufen von Event.preventDefault()
möglicherweise abbricht. Wenn der Event-Listener zu lange benötigt, um ausgeführt zu werden, kann dies zu einer merklichen Verzögerung führen, die auch als Jank bezeichnet wird, bevor die Standardaktion ausgeführt werden kann.
Indem die Option passive
auf true
gesetzt wird, erklärt der Event-Listener, dass er die Standardaktion nicht abbrechen wird, sodass der Browser die Standardaktion sofort starten kann, ohne auf den Abschluss des Listeners zu warten. Wenn der Listener dann Event.preventDefault()
aufruft, wird dies keine Wirkung haben.
Die Spezifikation für addEventListener()
definiert den Standardwert für die passive
-Option als immer false
. Um jedoch die Leistungsverbesserungen bei passiven Listenern im Legacy-Code zu realisieren, haben moderne Browser den Standardwert der passive
-Option für die wheel
-, mousewheel
-, touchstart
- und touchmove
-Ereignisse auf Dokumentebene auf Window
, Document
und Document.body
geändert. Das verhindert, dass der Event-Listener das Ereignis abbrechen kann, sodass er das Seitenrendering nicht blockieren kann, während der Benutzer scrollt.
Deshalb müssen Sie, wenn Sie dieses Verhalten überschreiben und sicherstellen möchten, dass die passive
-Option auf false
gesetzt ist, die Option explizit auf false
setzen (anstatt sich auf den Standardwert zu verlassen).
Sie müssen sich keine Gedanken über den Wert von passive
für das grundlegende scroll
-Ereignis machen. Da es nicht abgebrochen werden kann, können Event-Listener das Seitenrendering sowieso nicht blockieren.
Siehe Verbessern der Scroll-Leistung durch passive Listener für ein Beispiel, das den Effekt 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, die mit addEventListener()
registriert werden. Ein Klick irgendwo in der Tabelle bläst bis zum Handler hoch und führt modifyText()
aus.
Ergebnis
Einen abbrechbaren Listener hinzufügen
Dieses Beispiel zeigt, wie ein addEventListener()
-Ereignis 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 ändern wir den Code aus dem vorherigen Beispiel so, dass nachdem der Inhalt der zweiten Zeile zu "drei" gewechselt hat, wir abort()
vom AbortController
aufrufen, 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 Klickereignis hört.
Ergebnis
Event-Listener mit anonymer Funktion
Hier betrachten wir, wie eine anonyme Funktion verwendet wird, um Parameter an den Event-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(newText) {
const t2 = document.getElementById("t2");
t2.firstChild.nodeValue = newText;
}
// 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 umschließt, der dann wiederum in der Lage ist, Parameter an die modifyText()
-Funktion zu übergeben, die für das eigentliche Reagieren auf das Ereignis verantwortlich ist.
Ergebnis
Event-Listener mit einer Pfeilfunktion
Dieses Beispiel zeigt einen Event-Listener, der mit der Notation einer 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(newText) {
const t2 = document.getElementById("t2");
t2.firstChild.nodeValue = newText;
}
// 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 anonyme und Pfeilfunktionen zwar ähnlich sind, aber unterschiedliche this
-Bindungen haben. Während anonyme (und alle traditionellen JavaScript-Funktionen) ihre eigenen this
-Bindungen erstellen, erben Pfeilfunktionen die this
-Bindung der umgebenden Funktion.
Das bedeutet, dass die Variablen und Konstanten, die der umgebenden Funktion zur Verfügung stehen, auch dem Event-Handler zur Verfügung stehen, wenn eine Pfeilfunktion verwendet wird.
Beispiel zur 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://xyz03nm90t.proxynodejs.usequeue.com/" target="_blank">
inner1, passive & preventDefault(which is not allowed)
</a>
<a class="inner2" href="https://9wpyklyikk.proxynodejs.usequeue.com/" 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 und inneren Container, um zu sehen, wie die Optionen funktionieren.
Event-Listener mit mehreren Optionen
Sie können im options
-Parameter mehr als eine der Optionen setzen. Im folgenden Beispiel setzen wir zwei Optionen:
passive
, um zu bestätigen, dass der Handler nichtpreventDefault()
aufrufen wirdonce
, 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 mit passiven Listenern
Das folgende Beispiel zeigt den Effekt des Setzens von passive
. Es umfasst ein <div>
, das Text enthält, und ein Kontrollkästchen.
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 einen langlaufenden Vorgang aus. Der Listener wird zunächst mit der passive
-Option hinzugefügt, und immer wenn das Kontrollkästchen umgeschaltet wird, ändert der Code die passive
-Option.
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:
- Der Listener ist zu Beginn passiv, sodass das Scrollen des Containers mit dem Rad sofortig erfolgt.
- Wenn Sie "passive" deaktivieren und versuchen, den Container mit dem Rad zu scrollen, gibt es eine merkliche Verzögerung, bevor der Container scrollt, da der Browser warten muss, bis der langlaufende Listener fertig ist.
Spezifikationen
Specification |
---|
DOM # ref-for-dom-eventtarget-addeventlistener③ |