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
onclickstores 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 = nullversusremoveEventListener('click', handler). - Only
addEventListenersupports theonce,captureandpassiveoptions. - Only
addEventListenerlistens to any event type, custom ones included. - The inline
onclickHTML attribute works, but it mixes markup with logic; the modern practice isaddEventListenerin JavaScript.
Quick example
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
| Characteristic | onclick | addEventListener() |
|---|---|---|
| Number of handlers | only one, a new one overwrites the old | you can add several |
| Removal | just assign null | through removeEventListener() |
| Flexibility | a single event only, for example onclick | any event: click, keydown, scroll, input, custom |
| Extra settings | none | yes: once, capture, passive |
| Compatibility | the old way, supported everywhere | modern, supported in every current browser |
Overwriting versus a list of listeners
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:
Secondbecause the second one overwrote the first.
With addEventListener() both of them run:
btn.addEventListener('click', () => console.log('First'));
btn.addEventListener('click', () => console.log('Second'));On click:
First
SecondHow to detach a handler
With onclick it is enough to null the property:
btn.onclick = null; // removes the handlerWith addEventListener you need a reference to the very same function:
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:
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:
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:
<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.
onclick | addEventListener() | |
|---|---|---|
| Can assign several handlers | no | yes |
Can control behaviour (once, capture) | no | yes |
| Can listen to any event | no, click only | yes, any |
| Can be used directly in HTML | yes | no |
| Modern standard | legacy approach | recommended approach |
Conclusion:
onclickis 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 = fnadds 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
addEventListenerwhere 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
onclickproperty with the string attribute: in JavaScript you assign a function to it, not a line of code.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.