From a1d273b1c0d520f779ef9f4b26e6df1ef61dff92 Mon Sep 17 00:00:00 2001 From: "Michael[tm] Smith" Date: Sun, 28 Feb 2021 13:22:51 +0900 Subject: [PATCH 1/4] =?UTF-8?q?Copy=20edits=20for=20=E2=80=9CIntroduction?= =?UTF-8?q?=20to=20events=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../javascript/building_blocks/events/index.html | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/files/en-us/learn/javascript/building_blocks/events/index.html b/files/en-us/learn/javascript/building_blocks/events/index.html index fa89fd083ac3c80..6740709f79df5f8 100644 --- a/files/en-us/learn/javascript/building_blocks/events/index.html +++ b/files/en-us/learn/javascript/building_blocks/events/index.html @@ -181,9 +181,9 @@

Inline event handlers — don'

Note: Separating your programming logic from your content also makes your site more friendly to search engines.

-

addEventListener() and removeEventListener()

+

Adding and removing event handlers

-

The newest type of event mechanism is defined in the Document Object Model (DOM) Level 2 Events Specification, which provides browsers with a new function — addEventListener(). This functions in a similar way to the event handler properties, but the syntax is obviously different. We could rewrite our random color example to look like this:

+

The modern mechanism for adding event handlers is the addEventListener() method. Using it, we could rewrite our random color example to look like this:

const btn = document.querySelector('button');
 
@@ -198,14 +198,14 @@ 

addEventListener() and removeE

Note: You can find the full source code for this example on GitHub (also see it running live).

-

Inside the addEventListener() function, we specify two parameters — the name of the event we want to register this handler for, and the code that comprises the handler function we want to run in response to it. Note: It is perfectly appropriate to put all the code inside the addEventListener() function, in an anonymous function, like this:

+

Inside the addEventListener() function, we specify two parameters: the name of the event we want to register this handler for, and the code that comprises the handler function we want to run in response to it. Note: It is perfectly appropriate to put all the code inside the addEventListener() function, in an anonymous function, like this:

btn.addEventListener('click', function() {
   var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
   document.body.style.backgroundColor = rndCol;
 });
-

This mechanism has some advantages over the older mechanisms discussed earlier. First, there is a counterpart function, removeEventListener(), which removes a previously added listener. For example, this would remove the listener set in the first code block in this section:

+

This mechanism has some advantages over the older mechanisms discussed here earlier. First, there is a counterpart function, removeEventListener(), which removes a previously added event handler. For example, this would remove the event handler set in the first code block in this section:

btn.removeEventListener('click', bgChange);
@@ -213,10 +213,14 @@

addEventListener() and removeE

Second, you can register multiple handlers for the same listener. The following two handlers wouldn't both be applied:

+

For simple, small programs, cleaning up old, unused event handlers isn’t necessary — but for larger, more complex programs, it can improve efficiency. Plus, the ability to remove event handlers allows you to have the same button performing different actions in different circumstances — all you have to do is add or remove handlers.

+ +

The second advantage that {{domxref("EventTarget/addEventListener()", "addEventListener()")}} has over the older mechanisms discussed here earlier is that it allows you to register multiple handlers for the same listener. The following two handlers wouldn't both be applied:

+
myElement.onclick = functionA;
 myElement.onclick = functionB;
-

The second line overwrites the value of onclick set by the first line. This would work, however:

+

The second line overwrites the value of onclick set by the first line. What would work, however, is the following:

myElement.addEventListener('click', functionA);
 myElement.addEventListener('click', functionB);
From 9bf73ff26f582be808090d18efaa3e6aefa724b4 Mon Sep 17 00:00:00 2001 From: "Michael[tm] Smith" Date: Sun, 28 Feb 2021 13:29:26 +0900 Subject: [PATCH 2/4] =?UTF-8?q?Push=20=E2=80=9Cfix=20fixable=20flaws?= =?UTF-8?q?=E2=80=9D=20for=20removeEventListener()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../removeeventlistener/index.html | 20 +++++++++---------- .../guide/events/event_handlers/index.html | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/files/en-us/web/api/eventtarget/removeeventlistener/index.html b/files/en-us/web/api/eventtarget/removeeventlistener/index.html index 044c427af29f8a4..33ba268fdb65e05 100644 --- a/files/en-us/web/api/eventtarget/removeeventlistener/index.html +++ b/files/en-us/web/api/eventtarget/removeeventlistener/index.html @@ -2,15 +2,15 @@ title: EventTarget.removeEventListener() slug: Web/API/EventTarget/removeEventListener tags: -- API -- DOM -- DOM Element Methods -- EventTarget -- Gecko -- Method -- Reference -- browser compatibility -- removeEventListener + - API + - DOM + - DOM Element Methods + - EventTarget + - Gecko + - Method + - Reference + - browser compatibility + - removeEventListener ---
{{APIRef("DOM Events")}}
@@ -211,7 +211,7 @@

Polyfill to support older browsersaddEventListener() and removeEventListener() in implementations that do not natively support it. However, this method will not work on Internet Explorer 7 or earlier, since extending - the {{domxref("Element.prototype")}} was not supported until Internet Explorer 8.

+ the Element.prototype was not supported until Internet Explorer 8.

if (!Element.prototype.addEventListener) {
   var oListeners = {};
diff --git a/files/en-us/web/guide/events/event_handlers/index.html b/files/en-us/web/guide/events/event_handlers/index.html
index dbeeed62a22dd9e..24032179d9cca0d 100644
--- a/files/en-us/web/guide/events/event_handlers/index.html
+++ b/files/en-us/web/guide/events/event_handlers/index.html
@@ -103,7 +103,7 @@ 

Event handl
  • event, source, lineno, colno, and error for the {{domxref("GlobalEventHandlers.onerror", "onerror")}} event handler. Note that the event parameter actually contains the error message as a string.
  • -

    When the event handler is invoked, the this keyword inside the handler is set to the DOM element on which the handler is registered. For more details, see the this keyword documentation.

    +

    When the event handler is invoked, the this keyword inside the handler is set to the DOM element on which the handler is registered. For more details, see the this keyword documentation.

    The return value from the handler determines if the event is canceled. The specific handling of the return value depends on the kind of event; for details, see "The event handler processing algorithm" in the HTML specification.

    From f3b4a9b1356f20afd6733930252f32df82e75ab7 Mon Sep 17 00:00:00 2001 From: "Michael[tm] Smith" Date: Sun, 28 Feb 2021 13:33:58 +0900 Subject: [PATCH 3/4] Drop link to non-standard/undocumented detachEvent --- files/en-us/web/api/eventtarget/removeeventlistener/index.html | 1 - 1 file changed, 1 deletion(-) diff --git a/files/en-us/web/api/eventtarget/removeeventlistener/index.html b/files/en-us/web/api/eventtarget/removeeventlistener/index.html index 33ba268fdb65e05..2f5b0b84c5a834c 100644 --- a/files/en-us/web/api/eventtarget/removeeventlistener/index.html +++ b/files/en-us/web/api/eventtarget/removeeventlistener/index.html @@ -268,5 +268,4 @@

    See also

    • {{domxref("EventTarget.addEventListener()")}}
    • -
    • {{non-standard_inline}}{{domxref("EventTarget.detachEvent()")}}
    From 8e31499002c5de70df4e0d21d3966210ccb3a463 Mon Sep 17 00:00:00 2001 From: "Michael[tm] Smith" Date: Sun, 28 Feb 2021 13:37:32 +0900 Subject: [PATCH 4/4] Document abortable event listeners MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch includes the following changes: - Document the "signal" parameter for the addEventListener() options object - “Add an abortable listener” example code added to addEventListener() article - Add a similar simple example code to he “Introduction to events” guide - In both “Introduction to events” guide and removeEventListener() article, add prose mentions that you can pass an AbortSignal to an addEventListener() call, and abort/cancel/remove the listener by calling abort() on the controller owning the AbortSignal. Related: - https://github.com/whatwg/dom/commit/83037a1 - https://dom.spec.whatwg.org/#dictdef-addeventlisteneroptions - https://dom.spec.whatwg.org/#ref-for-concept-event-listener① - https://dom.spec.whatwg.org/#ref-for-abortsignal③ --- .../building_blocks/events/index.html | 12 +++++- .../eventtarget/addeventlistener/index.html | 40 +++++++++++++++++++ .../removeeventlistener/index.html | 2 + .../guide/events/event_handlers/index.html | 2 +- 4 files changed, 53 insertions(+), 3 deletions(-) diff --git a/files/en-us/learn/javascript/building_blocks/events/index.html b/files/en-us/learn/javascript/building_blocks/events/index.html index 6740709f79df5f8..8d6ee43e3ac0927 100644 --- a/files/en-us/learn/javascript/building_blocks/events/index.html +++ b/files/en-us/learn/javascript/building_blocks/events/index.html @@ -209,9 +209,17 @@

    Adding and removing event handlersbtn.removeEventListener('click', bgChange);

    -

    This isn't significant for simple, small programs, but for larger, more complex programs it can improve efficiency to clean up old unused event handlers. Plus, this allows you to have the same button performing different actions in different circumstances — all you have to do is add or remove event handlers as appropriate.

    +

    Event handlers can also be removed by passing an {{domxref("AbortSignal")}} to {{domxref("EventTarget/addEventListener()", "addEventListener()")}} and then, later, calling {{domxref("AbortController/abort()", "abort()")}} on the controller owning the AbortSignal. For example, to add an event handler that we can remove with an AbortSignal:

    -

    Second, you can register multiple handlers for the same listener. The following two handlers wouldn't both be applied:

    +
    const controller = new AbortController();
    +btn.addEventListener('click', function() {
    +  var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
    +  document.body.style.backgroundColor = rndCol;
    +}, { signal: controller.signal }); // pass an AbortSignal to this handler
    + +

    Then the event handler created by the code above can be removed like this:

    + +
    controller.abort(); // removes any/all event handlers associated with this controller

    For simple, small programs, cleaning up old, unused event handlers isn’t necessary — but for larger, more complex programs, it can improve efficiency. Plus, the ability to remove event handlers allows you to have the same button performing different actions in different circumstances — all you have to do is add or remove handlers.

    diff --git a/files/en-us/web/api/eventtarget/addeventlistener/index.html b/files/en-us/web/api/eventtarget/addeventlistener/index.html index 263c8a192b56a37..1876a15793037fa 100644 --- a/files/en-us/web/api/eventtarget/addeventlistener/index.html +++ b/files/en-us/web/api/eventtarget/addeventlistener/index.html @@ -70,6 +70,8 @@

    Parameters

    does call preventDefault(), the user agent will do nothing other than generate a console warning. See Improving scrolling performance with passive listeners to learn more. +
    signal
    +
    An {{domxref("AbortSignal")}}. The listener will be removed when the given AbortSignal’s {{domxref("AbortController/abort()", "abort()")}} method is called.
    {{non-standard_inline}} mozSystemGroup
    A {{jsxref("Boolean")}} indicating that the listener should be added to the system group. Available only in code running in XBL or in the @@ -249,6 +251,44 @@

    Result

    {{EmbedLiveSample('Add_a_simple_listener')}}

    +

    Add an abortable listener

    + +

    This example demonstrates how to add an addEventListener() that can be aborted with an {{domxref("AbortSignal")}}.

    + +

    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"
    +  }
    +}
    +
    +
    + +

    In the above example just above, we modify the code in the previous example such that after the second row’s content changes to "three", we call abort() from the {{domxref("AbortController")}} we passed to the addEventListener() call. That results in the value remaining as "three" forever — because we no longer have any code listening for a click event.

    + +

    Result

    + +

    {{EmbedLiveSample('add_a_abortable_listener')}}

    +

    Event listener with anonymous function

    diff --git a/files/en-us/web/api/eventtarget/removeeventlistener/index.html b/files/en-us/web/api/eventtarget/removeeventlistener/index.html index 2f5b0b84c5a834c..73472560b783297 100644 --- a/files/en-us/web/api/eventtarget/removeeventlistener/index.html +++ b/files/en-us/web/api/eventtarget/removeeventlistener/index.html @@ -22,6 +22,8 @@ and various optional options that may affect the matching process; see {{anch("Matching event listeners for removal")}}

    +

    Note that event listeners can also be removed by passing an {{domxref("AbortSignal")}} to an {{domxref("EventTarget/addEventListener()", "addEventListener()")}} and then later calling {{domxref("AbortController/abort()", "abort()")}} on the controller owning the signal.

    +

    Syntax

    Registering onevent handlers

    document.querySelector("button").onclick = function(event) { … }. -

    An onevent's event handler property serves as a placeholder of sorts, to which a single event handler can be assigned. In order to allow multiple handlers to be installed for the same event on a given object, you can call its {{domxref("EventTarget.addEventListener", "addEventListener()")}} method, which manages a list of handlers for the given event on the object. A handler can then be removed from the object by calling its {{domxref("EventTarget.removeEventListener", "removeEventListener()")}} function.

    +

    An onevent's event handler property serves as a placeholder of sorts, to which a single event handler can be assigned. In order to allow multiple handlers to be installed for the same event on a given object, you can call its {{domxref("EventTarget.addEventListener", "addEventListener()")}} method, which manages a list of handlers for the given event on the object. A handler can then be removed from the object either by calling its {{domxref("EventTarget.removeEventListener", "removeEventListener()")}} function, or else, if an {{domxref("AbortSignal")}} was passed to the {{domxref("EventTarget/addEventListener()", "addEventListener()")}} which set the handler, calling {{domxref("AbortController/abort()", "abort()")}} on the controller owning the signal.

    When an event occurs that applies to an element, each of its event handlers is called to allow them to handle the event, one after another. You don't need to call them yourself, although you can do so in many cases to easily simulate an event taking place. For example, given a button object myButton, you can do myButton.onclick(myEventObject) to call the event handler directly. If the event handler doesn't access any data from the event object, you can leave out the event when calling onclick().