Binding Event Handlers

Inline attributes (onclick="...") are blocked by a strict Content Security Policy, and a handler property (el.onclick = fn) holds only one function. addEventListener(type, listener, options) allows many listeners and takes these options:

addEventListener options (*default true for wheel and touch events on window, document and body, except in Safari 10 )
Option Effect when true or set
capture Run in the capture phase, not the bubble phase
once Remove the listener after its first call
passive Never call preventDefault(), so scrolling need not wait*
signal Remove the listener when its AbortController aborts
once and signal remove listeners for youHTMLLive
<button>Buy</button> <output></output>
<script>
  const [btn, out] = document.querySelectorAll("button, output");
  const ctrl = new AbortController();
  btn.addEventListener("click", () => out.append("once "), { once: true });
  btn.addEventListener("click", () => out.append("signal "), { signal: ctrl.signal });
  btn.click();
  ctrl.abort();   // removes every listener registered with this signal
  btn.click();    // adds nothing
</script>
Browser output of Listing 8.42
Browser output of 42

In a regular function handler this is the element; arrow functions do not bind it, so use event.currentTarget.