Skip to main content Accessibility Feedback

JavaScript event delegation across a code base

I’m a big fan of event delegation. If you’re unfamiliar with the concept, here’s a quick overview.

A common follow-up question I get when advocating this approach is how to handle event listeners across several JavaScript modules are components.

For example, let’s say you had components for an accordion, toggle tabs, and a modal window. All three use a click event listener.

Should you use a single event listener for all three components, or three separate ones—one in each component?

/**
 * All-in-one
 */
document.addEventListener('click', function (event) {

	if (event.target.matches('.accordion')) {
		// Do accordion stuff
	}

	if (event.target.matches('.tab')) {
		// Do tab stuff
	}

	if (event.target.matches('.modal')) {
		// Do modal stuff
	}

}, false);

/**
 * Three Separate listeners
 */

var accordion = function () {

	// All the other code...

	document.addEventListener('click', function (event) {
		if (event.target.matches('.accordion')) {
			// Do accordion stuff
		}
	}, false);

};

var tabs = function () {

	// All the other code...

	document.addEventListener('click', function (event) {
		if (event.target.matches('.tab')) {
			// Do accordion stuff
		}
	}, false);

};

var modals = function () {

	// All the other code...

	document.addEventListener('click', function (event) {
		if (event.target.matches('.modal')) {
			// Do accordion stuff
		}
	}, false);

};

The “all-in-one” approach is better for performance.

I personally use the second approach, because I like to keep my listeners with their components and maintain modular code bases.

I think it’s more important to delegate events within a component than across your entire code base. That’s where you’ll see the biggest gains in performance.

Tomorrow, I’m going to share a small helper library I wrote to let you get the best of both worlds.