addEventListener vs onclick: Which one should you draft into your fantasy football team?

Anna Peterson
4 min readNov 4, 2019

--

a lady wizard riding a unicorn and holding a football with text fantasy football
Anyone else imagining wizards on unicorns tossing the ol’ pigskin every time they hear the words ‘fantasy football’?

target.addEventListener(‘click’, myFunction) OR onclick=“(myFunction)”? Which one should I use? And which one of them could be a sleeper? — That’s fantasy football lingo for a secretly good player.

Time to learn about event objects!

onclick is a property of the GlobalEventHandlers mixin. It processes click events on an element. onclick is also an HTML event attribute that can call a function without the need for script tags.

We like to keep languages separate, we like to keep the behavior side of things in our JavaScript, and the structural or presentational elements in our HTML. With the GlobalEventHandlers mixin we can still use target.onclick right in our JS, though. That just about levels the playing field, right? What’s more, the addEventListener() method is not supported in Internet Explorer 8 and earlier versions. Looks good for onclick so far.

Let’s be real though, who cares about people still using Internet Explorer 8? Even Microsoft itself no longer provides support for that thing. People who use IE8 are wrong, not developers who use addEventListener.

Here’s where we see behavioral differences:

JS:

const first = document.getElementById("first");
const second = document.getElementById("second");
function handler1() {
alert("First handler");
}
function handler2() {
alert("Second handler");
}
first.addEventListener("click", handler1);
first.addEventListener("click", handler2);
second.onclick = handler1;
second.onclick = handler2;

HTML:

<div id="first">First Element</div>
<div id="second">Second Element</div>

Clicking “First Element” will trigger 2 alerts. Clicking on “Second Element” will trigger only the second alert! With addEventListener, you can attach multiple events to the same element, but not with onclick.

Quick note: For accessibility reasons, it’s best practice to include a keydown event in addition to a click event.

BUT WAIT, there’s more to learn from addEventListener. Have you ever looked at the optional third argument addEventListener takes?

If you have 3 elements with element 3 nested inside element 2 nested inside element 1, and functions called handler1, handler2, and handler3 attached to the corresponding elements what order will they trigger in? (see diagram)

a diagram showing 3 concentric rectangles: div, span, button, and an arrow pointing out: event bubbling
event bubbling via Wikipedia

That all depends on how the event propagates. No matter where you put your handler, the most nested element is considered the target. The element where the event originated is called the currentTarget.

You can see how event bubbling and capturing work on nested elements and propagate through the DOM tree with this repl. Due to repl.it’s way of logging console.time(), you can get the most accurate results by copying and pasting the code into a local file and testing it in your browser.

Our event passes through three phases:

The capture phase: The event object propagates through the target’s ancestors from the Window to the target’s parent. This phase is also known as the capturing phase.

The target phase: The event object arrives at the event object’s event target. This phase is also known as the at-target phase. If the event type indicates that the event doesn’t bubble, then the event object will halt after completion of this phase.

The bubble phase: The event object propagates through the target’s ancestors in reverse order, starting with the target’s parent and ending with the Window. This phase is also known as the bubbling phase.

-w3.org documentation

These also happen to be the phases of a quarantine.

The events that bubble will trigger like this: handler3 → handler2 → handler1. The outermost element’s handler triggers last. Events with useCapture: true? They will go in the opposite order. onclick will always default to false for that third argument. There are limited use cases for using that argument and most of them wouldn’t apply to a ‘click’ event, but it can prepare or prevent behavior that will later be applied by event delegation during the bubbling phase.

React

While this takes us outside the scope of vanilla JS and HTML, JSX handles events differently and eschews event listeners almost entirely. Because React is so popular, it doesn’t hurt to be familiar with the HTML inline onclick syntax (note that JSX uses camelCase rather than lower case so it becomes onClick). Similarly, jQuery events do not use capture in most cases and onclick will work just fine for attaching a single click event succinctly. This makes onclick the sleeper that you may want on your fantasy football team.

At the end of the day, what’s most important is which game you’re playing. Remember that football can mean different things in different contexts (such as the U.S.A. vs almost everywhere else). So, understand which player is going to be most successful in each context. More importantly, think about how events propagate and trigger in the DOM tree. I’d pick addEventListener in vanilla JS because it’s more robust and generally preferred, but onclick works just fine most of the time and becomes especially useful when introducing React. This metaphor’s stretching like Mister Fantastic so let’s just read some documentation and relax!

onclick

The onclick property of the GlobalEventHandlers mixin is the EventHandler for processing click events on a given element.

The click event is raised when the user clicks on an element. It fires after the mousedown and mouseup events, in that order.

MDN

addEventListener

The EventTarget method addEventListener() sets up a function that will be called whenever the specified event is delivered to the target. Common targets are Element, Document, and Window, but the target may be any object that supports events (such as XMLHttpRequest).

addEventListener() works by adding a function or an object that implements EventListener to the list of event listeners for the specified event type on the EventTarget on which it's called.

MDN

--

--

Anna Peterson

As an Austin-based developer, my writing is focused on making tech more fun and approachable.