Javascript: let’s meet the event object

Tovi Newman
Launch School
Published in
6 min readJul 25, 2017

Whenever you interact with your browser, your browser creates an event object.

This event object has properties that describe that interaction.

In order to convert any given event into productive work, we need to create an “event handler” and register it with an element object from the DOM. For example: someElement.addEventHandler('click', someFunction);

Now, when our event object encounters an element with an event handler that meets certain criteria (we will talk about this in a bit), the handler will be triggered, and the function that it contains will execute. But how do events encounter event handlers?

The short answer is that the event object must find and “fire” on all of the elements that could potentially have listeners registered to them for that event. Let’s learn how the browser achieves this.

One important property of an event object is “target”. The event target is the inner most nested element that was targeted by the event (e.g., the element that was clicked). The event object is about to go on a journey and the event target is its destination.

To access the target element property use event.target

In most cases, the “event path” starts at Window. From there, the event object “fires” on each ancestor element of the target as it moves toward the target. This is called the “capture phase”.

Capture phase: dramatic reenactment

Once the event reaches the destination it finally gets to fire on the target element, just in case the target itself has an event handler registered to it. This is called the “target phase.”

Now, our event object must make the return trip.

The return trip back up to Window is called the “bubble phase.”

No elements were harmed in the making of this sketch

Just remember, capture down, bubble up.

Just remember, capture down, bubble up.

This round trip through all three phases is called the “event propagation path.”

Lets put the event propagation path aside for a moment and talk about what happens to an element when it is fired on by the event object. First off, the element that the event object is firing on at any given moment is called the “current target.”

To access the current target property use event.currentTarget

Questions: How does the current target know whether or not to execute its function when an event object fires on it? Also, how do handlers avoid getting triggered twice, once for each (capture/bubble) phase?

Answer: If the currentTarget has an event handler attached to it that matches the event type and the handler is set to be triggered on the same phase that the event object is in, the handler will execute its function.

Handler not triggered.
Handler triggered!

The reason there are three phases (capture, target, and bubble) is partially due to historical implementation and partially due to maximizing flexibility. In the past, different browsers chose to handle events in only one direction. Internet Explorer chose to only bubble, while most other browsers chose to only capture. These days, modern browsers default to handle most events on the bubble phase but allow developers the option of capturing instead. This flexibility allows developers greater control over when handlers are triggered.

To review, event propagation can be broken into three phases.

  1. The capture phase — event object starts at Window and moves towards event target firing on every element in its path.
  2. The target phase —event fires only once on the target element.
  3. The bubble phase — event fires on the parent of the target and keeps firing all the way back to Window.

Now that we’ve got some concepts down, let’s dive into some code!

First let’s register an event handler with a very important event type. DOMContentLoaded This handler will trigger only after the DOM elements are loaded. Check it out!

But where is that event object? Let’s pass him into the function!

There he is! Cute little fella. Let’s look at the event object’s propagation path by checking the path property.

There are just two elements here, that is because we started at window and our target is the document. Let’s check the target property to make sure.

It is common practice to nest all of your other listeners within this initial one. If you don’t, the nested elements that you register your other handlers to might not exist yet! This can be a little hard to demonstrate online because codepen and other sites make sure that the DOM is loaded before any scripts are read. But this wont always be the case in other environments such as your browser. Better to be safe than buggy.

Now that we’ve built our first event listener, let’s add some html with a div and attach a click handler to the document element.

Now let’s pass our event object to the function and see what the path and the target are. What do you think the target will be? Check it out.

So the target was the div element! That makes sense because even though we attached the click handler to the document, we targeted the div by clicking on it, and the div was nested within document. Try clicking outside the div.

So, what if we retrieve the currentTarget from the event object after clicking on div? What do you think we will find?

The currentTarget of the event object is always going to be whatever element the event object is visiting at that moment in time. Since the alert code was triggered by the handler that the event object was visiting, the element connected to the handler at that moment is the currentTarget.

Now let’s play with bubble, target, and capture.

Let’s do a couple things:

  1. Let’s streamline our syntax a little by declaring our functions. Let’s make one that alerts ‘capture!’ and one that alerts ‘bubble!’.
  2. Let’s add another click handler so we have one for each function. To set a handler to capture, pass true as a third parameter to the function. For consistency, pass false to the handler that we want to bubble.
  3. Which handler do you think will trigger first?

Now, just for fun, let’s register our handlers to the div instead. Oh no! Why did the bubble handler get triggered first?!

See if you can figure this one out on your own :)

That’s all for now. Thanks for reading!

--

--