Blog

Onclick JavaScript: onclick vs addEventListener for Handling Button Events

Use addEventListener() for most button events. Use onclick only for tiny demos, quick tests, or simple one-off pages. The reason is simple. addEventListener() lets many pieces of code listen to the same button, while onclick usually lets one handler sit in the main seat. The method has been widely supported in browsers for years [source: MDN].

TLDR: onclick is quick, but addEventListener() is cleaner and safer for real projects. Example: one “Buy Now” button may need to open a cart, send analytics, and change the button text. With onclick, the second script can overwrite the first one. On a small shop page with 12 buttons, using addEventListener() can avoid hours of “why did my click stop working?” pain.

The tiny version

A button click is just a signal. The user taps or clicks. The browser says, “Hey, something happened.” Your JavaScript responds.

There are two common ways to do that:

  • onclick: attach one click action directly.
  • addEventListener(): register one or many click actions.

Both work. Both can run code when a button is clicked. But they do not scale the same way.

What is onclick?

onclick is the old, simple way.

<button onclick="sayHi()">Click me</button>

<script>
function sayHi() {
  alert("Hi!");
}
</script>

This is easy to read. It feels friendly. It is great when you are learning.

You can also set it in JavaScript:

const button = document.querySelector("#saveBtn");

button.onclick = function () {
  console.log("Saved!");
};

Nice and short.

But here comes the annoying bit. If another script assigns button.onclick again, the first function is replaced.

button.onclick = function () {
  console.log("Saved!");
};

button.onclick = function () {
  console.log("Tracked!");
};

Only "Tracked!" runs. The save action is gone. Poof. Have fun losing 25 minutes to that bug.

What is addEventListener()?

addEventListener() is the more flexible way.

const button = document.querySelector("#saveBtn");

button.addEventListener("click", function () {
  console.log("Saved!");
});

It says: “When this event happens, run this function.”

You can also add more than one listener:

button.addEventListener("click", function () {
  console.log("Saved!");
});

button.addEventListener("click", function () {
  console.log("Tracked!");
});

Now both run. No one gets kicked out.

This matters a lot in real projects. One team might handle form saving. Another might handle analytics. A third might add a loading spinner. With addEventListener(), they can all listen to the same click without stomping on each other.

Quick comparison

Feature onclick addEventListener()
Easy for beginners Yes Yes, after a minute
Multiple handlers Not in the same clean way Yes
Good for large apps Not really Yes
Can remove handler Yes, but clunky Yes, cleanly
Best habit For tiny scripts For most work

Why inline onclick can get messy

Inline onclick puts JavaScript inside HTML.

<button onclick="deleteUser(42)">Delete</button>

That may look harmless. Then the button needs a confirmation box. Then a loading state. Then analytics. Then a permission check. Suddenly your HTML looks like it lost a fight with spaghetti.

Honestly, it feels like taping a remote control to a toaster. It works. But nobody wants to maintain it.

A cleaner pattern is this:

<button id="deleteBtn" data-user-id="42">Delete</button>

<script>
const deleteBtn = document.querySelector("#deleteBtn");

deleteBtn.addEventListener("click", function () {
  const userId = deleteBtn.dataset.userId;
  console.log("Delete user", userId);
});
</script>

Your HTML stays about structure. Your JavaScript handles behavior. Much nicer.

When onclick is okay

onclick is not evil. It is just limited.

Use it when:

  • You are learning JavaScript.
  • You are making a tiny demo.
  • You need a fast test in a code playground.
  • You control the whole page.
  • No other script needs the same button.

For example:

<button onclick="alert('Boom!')">Surprise</button>

That is fine. It is silly. It works. Ship the tiny clown button.

When addEventListener() is better

Use addEventListener() when the project matters even a little.

Pick it when:

  • You have more than one button.
  • You work with a team.
  • You use analytics.
  • You use modules or build tools.
  • You may add more behavior later.
  • You care about clean code.

It also supports options. One neat option is once. It runs the handler one time only.

button.addEventListener("click", function () {
  console.log("This runs once.");
}, { once: true });

That is perfect for things like a “Start Trial” button. The user clicks. The action starts. The handler removes itself. No double fire. No weird repeat.

How to remove a click listener

Sometimes you need to remove a handler. Maybe a modal closes. Maybe a game round ends. Maybe the button should stop reacting.

With addEventListener(), use a named function.

function handleClick() {
  console.log("Clicked!");
}

button.addEventListener("click", handleClick);

button.removeEventListener("click", handleClick);

The key is using the same function name. If you use an anonymous function, removal gets awkward fast.

This is one of those bugs that wastes time in a very rude way. You click once, but the app acts like you clicked three times. Then you realize old listeners are still hanging around like uninvited raccoons.

A real user case

Imagine a newsletter page with one big button: Subscribe.

At first, the button has one job:

  • Send the email address.

Then marketing asks for more:

  • Track the click.
  • Show a spinner.
  • Disable the button.
  • Display a thank you message.

Now one click has five jobs. With onclick, you may cram them into one function. That function gets fat. It gets grumpy. It starts doing too much.

With addEventListener(), you can split the work:

subscribeBtn.addEventListener("click", sendEmail);
subscribeBtn.addEventListener("click", trackSignup);
subscribeBtn.addEventListener("click", showSpinner);
subscribeBtn.addEventListener("click", disableButton);

Each function has one job. That is easier to test. It is easier to fix. It is easier to read on Monday morning with weak coffee.

Best practice pattern

Here is a friendly everyday setup:

<button id="likeBtn">Like</button>

<script>
const likeBtn = document.querySelector("#likeBtn");

function handleLikeClick() {
  likeBtn.textContent = "Liked!";
  console.log("User liked this.");
}

likeBtn.addEventListener("click", handleLikeClick);
</script>

This is clear. The HTML is simple. The JavaScript is easy to scan. The function name tells you what happens.

So, which one should you choose?

Choose addEventListener() by default.

It is more flexible. It supports multiple handlers. It keeps HTML cleaner. It works better as your code grows.

Choose onclick when you need something tiny and disposable. A lesson. A quick test. A funny button that says “Banana.”

Here is the rule of thumb:

  • Learning or demo? onclick is okay.
  • Real page? Use addEventListener().
  • Team project? Use addEventListener().
  • Many button jobs? Use addEventListener().

Button clicks should be boring in the best way. They should work. They should be easy to change. They should not turn into a mystery at 4:57 PM.

So yes, onclick still has a place. But for clean button events, addEventListener() is the grown-up choice.