Are You Listening to This?

Execution context in JavaScript and jQuery event listeners

The Event Handler

Let’s set up the function we’ll be using as an event handler throughout this demo:

Attach To All Children

A naive way of doing this might be to add an event listener to each <li> or <a> element in the list. Let’s do that here:

Attach To Parent

Instead, we can take advantage of event propagation and let the parent <ul> element handle any click event on one of its children:

Beware the Arrow!

One thing to note here is that using an ES6 arrow function can be problematic if you want to rely on the value of this. Since arrow functions do not have their own binding to this, it will use the value of thiswhere the function is defined (usually window or document depending on whether you are defining it in the global scope or inside of an event listener like a DOMContentLoaded listener).

CodePen example of JavaScript Event Listeners

Attach To Children With jQuery

With jQuery we can use the on() method to attach a listener. If you are unfamiliar, check out the documentation. There are a few different ways of calling this method and we won’t cover them all.

Attach To Parent With jQuery

This will go through the list of <li>elements and attach a click event listener to each one. This means that this is set to each <li>element. But this technique suffers from the same inefficiency as in vanilla JS, as well as the need to attach listeners to any new elements as we add them.

The Best of Both Worlds

But, in jQuery we can do one better. The on() method allows us to pass a selector argument. The docs say this is:

Wrapping Up

Let’s quickly review some takeaways:

  1. In general, the execution context for an event handler will be the element to which the handler is added. This is usually going to be the same as the event.currentTarget property.
  2. If you use an arrow function as the event handler, your execution context will not be the element and will most likely be either window or document instead.
  3. We can use the jQuery method on() to attach a single event handler to a parent element but use the selector argument to filter events based on whether the event has bubbled from or through an element that matches the selector string. This has the benefit of setting both this and currentTarget as if the handler were attached to the child element, while maintaining the efficiency and flexibility of delegating event handling to the parent.

Further Exploration

If you’re intrigued by this and want to have some more fun, try to implement a jQuery “selector style” event listener in plain JavaScript. I have successfully implemented most of the functionality, including the correct this within the callback. The tricky part is to get event.currentTarget to point to the selected child instead of the parent element where the event is attached. I haven’t spent the time to research that yet.

--

--

Husband and father of two. Software engineer. Musician.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store