Skip to main content

onclick vs addEventListener

onclick is a property of a DOM element that holds exactly one handler, while addEventListener() is a method that appends a handler to the element's list of event listeners. Every other difference follows from that: how many handlers you get, how you detach them, which options are available and which event types you can listen to.

Theory

TL;DR

  • onclick stores a single handler, and assigning again overwrites the previous one.
  • addEventListener() appends handlers to a list, and they run in the order they were added.
  • Removal: onclick = null versus removeEventListener('click', handler).
  • Only addEventListener supports the once, capture and passive options.
  • Only addEventListener listens to any event type, custom ones included.
  • The inline onclick HTML attribute works, but it mixes markup with logic; the modern practice is addEventListener in JavaScript.

Quick example

javascript
const btn = document.querySelector('#btn'); // one handler: the second line overwrites the first btn.onclick = () => console.log('First'); btn.onclick = () => console.log('Second'); // a list of listeners: both will run btn.addEventListener('click', () => console.log('A')); btn.addEventListener('click', () => console.log('B'));

The core difference

CharacteristiconclickaddEventListener()
Number of handlersonly one, a new one overwrites the oldyou can add several
Removaljust assign nullthrough removeEventListener()
Flexibilitya single event only, for example onclickany event: click, keydown, scroll, input, custom
Extra settingsnoneyes: once, capture, passive
Compatibilitythe old way, supported everywheremodern, supported in every current browser

Overwriting versus a list of listeners

javascript
const btn = document.querySelector('#btn'); // the first handler btn.onclick = () => console.log('First'); // the second handler btn.onclick = () => console.log('Second');

On click the console shows only:

text
Second

because the second one overwrote the first.

With addEventListener() both of them run:

javascript
btn.addEventListener('click', () => console.log('First')); btn.addEventListener('click', () => console.log('Second'));

On click:

text
First Second

How to detach a handler

With onclick it is enough to null the property:

javascript
btn.onclick = null; // removes the handler

With addEventListener you need a reference to the very same function:

javascript
function handler() { console.log('click'); } btn.addEventListener('click', handler); btn.removeEventListener('click', handler);

That is exactly why an anonymous arrow passed to addEventListener can no longer be removed: nothing holds a reference to it.

Options and arbitrary event types

Options exist only on addEventListener:

javascript
btn.addEventListener('click', handler, { once: true });

The handler runs only once and detaches itself automatically. onclick cannot do that.

In the same way, only addEventListener listens to any event type, custom ones included:

javascript
element.addEventListener('myCustomEvent', () => console.log('custom event!'));

With onclick you can only subscribe to a click; for other events you would need separate properties such as onkeydown or onscroll, and each of them again holds a single handler.

Inline onclick in HTML and a summary

A handler can be written straight into the markup:

html
<button onclick="alert('Hello')">Click me</button>

This is not recommended, though: it mixes structure with logic (JavaScript inside HTML) and is hard to maintain. The modern practice is always addEventListener() in JavaScript.

onclickaddEventListener()
Can assign several handlersnoyes
Can control behaviour (once, capture)noyes
Can listen to any eventno, click onlyyes, any
Can be used directly in HTMLyesno
Modern standardlegacy approachrecommended approach

Conclusion: onclick is simple but dated, suitable at best for tiny tasks. addEventListener() is the modern, flexible and correct way to wire up events in JavaScript.

Common mistakes

  • Assuming btn.onclick = fn adds another handler: it silently wipes the previous one and someone else's code stops working.
  • Mixing both approaches on one element and then wondering why only part of the logic runs.
  • Passing an anonymous function to addEventListener where it will later need to be removed.
  • Writing onclick="..." in HTML for speed: such code cannot be covered by tests and clashes with content security policies (CSP).
  • Confusing the onclick property with the string attribute: in JavaScript you assign a function to it, not a line of code.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.