Skip to main content Accessibility Feedback

JavaScript Debugging Basics: Part 1

One of the biggest things people who buy my pocket guides and courses ask me about is debugging.

Today, I wanted to help you learn how to debug your code, and I thought the best way to do that would be with a practical example sent in by an actual reader.

The Problem

You run an animal rescue, and you want users to select the types of adoptable animals they’re interested in—dogs, cats, lizards, and so on.

Clicking a “Filter” button shows the list of available pets. When the list opens, there’s also a “Close” button users can click to hide the list.

The close button currently does not work. Why not?

The Code

You can view a working demo of the code here.

It builds on an article I wrote on how to show and hide content with vanilla JS, and how to use event bubbling and delegation.

The HTML

Our buttons have a [data-toggle] attribute on them. This attribute contains the ID of the element to show or hide, and is used by our script to toggle visibility.

<button class="btn" data-toggle="#example">
	Filter
</button>

<br><br>

<div class="toggle-content" id="example">
	<button class="btn btn-secondary" data-toggle="#close">
		Close
	</button>

	<h2>Pet Types</h2>

	<label>
		<input type="checkbox" name="dogs">
		Dogs
	</label>
	<br>

	<label>
		<input type="checkbox" name="cats">
		Cats
	</label>
	<br>

	<label>
		<input type="checkbox" name="birds">
		Birds
	</label>
	<br>

	<label>
		<input type="checkbox" name="snakes">
		Snakes
	</label>
	<br>

	<label>
		<input type="checkbox" name="lizards">
		Lizards
	</label>
</div>

CSS

By default, content with the .toggle-content class is hidden. When it also has the .is-visible class, we’ll show it.

This class is added dynamically with JavaScript.

/**
 * Hide toggled content by default
 */
.toggle-content {
	display: none;
}

/**
 * Show toggled content when the .is-visible class is added
 */
.toggle-content.is-visible {
	display: block;
}

/**
 * Style the buttons
 */
.btn {
	background-color: #0088cc;
	border: 1px solid #0088cc;
	color: #ffffff;
	display: inline-block;
	padding: 0.5em 0.6875em;
}

.btn-secondary {
	background-color: #808080;
	border-color: #808080;
}

The JavaScript

The script includes three helper methods to show, hide, and toggle visibility on content.

It also includes an event listener to listen for clicks on the document. If the clicked element has a [data-toggle] attribute, we’ll use it to find our content area and toggle visibility.

/**
 * Helper methods
 * https://gomakethings.com/how-to-show-and-hide-elements-with-vanilla-javascript/
 */

// Show an element
var show = function (elem) {
	elem.classList.add('is-visible');
};

// Hide an element
var hide = function (elem) {
	elem.classList.remove('is-visible');
};

// Toggle element visibility
var toggle = function (elem) {
	elem.classList.toggle('is-visible');
};

/**
 * Listen for all clicks on the document
 * https://gomakethings.com/checking-event-target-selectors-with-event-bubbling-in-vanilla-javascript/
 */
document.addEventListener('click', function (event) {

	// Make sure clicked element is our toggle
	// To do this, make sure it has the data-toggle attribute
	var toggleId = event.target.getAttribute('data-toggle');

	// If the clicked element doesn't have a data-toggle attribute, bail
	if (!toggleId) return;

	// Prevent default link behavior
	event.preventDefault();

	// Get the content that has the same ID as the data-toggle value
	var content = document.querySelector(toggleId);

	// If no matching element is found, bail
	if (!content) return;

	// Toggle the content
	toggle(content);

}, false);

Your challenge

So… what’s wrong with this script? Why isn’t the “Close” button working as expected?

I’ll walk through how I would debug this script and show you what’s wrong tomorrow. But first, Why don’t you give it a shot?

Email me with your answer, what you tried, anything that has you tripped up, or event unsuccessful attempts at solving it. I’ve got a special surprise for those of you who do (this offer ends when the next article goes live tomorrow). (The offer has expired.)