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:
| 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 |
<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>
In a regular function handler this is the element; arrow functions do not bind it, so use event.currentTarget.