Create a Counter in JavaScript in Five Steps

Introduction

Problem Solving

Step 1: Create the Interface

First, define a counter block that displays the current number and contains a container buttonGroup with buttons for “subtract, reset, and add.”

<div class="counter">
<div id="counterDisplay" class="counter__display"></div>
<div id="buttonGroup" class="buttonGroup">
<button class="button" id="minus">-</button>
<button class="button" id="reset">Reset</button>
<button class="button" id="add">+</button>
</div>
</div>

Step 2: Select Screen Elements

Use the previously defined id attributes to select each DOM element (using the getElementById🔗 method) and store them in variables.

// Select screen elements
const counterDisplay = document.getElementById('counterDisplay');
const counterMinusButton = document.getElementById('minus');
const counterResetButton = document.getElementById('reset');
const counterAddButton = document.getElementById('add');
const counterButtons = document.getElementById('buttonGroup');

Step 3: Render Data on the Screen

Currently, the counterDisplay has no content, so we can define a piece of data and render it on the screen; since “rendering data on the screen” is a highly repetitive action, we can isolate it into a function to call when needed.

const counter = 0;
function renderCounter() {
counterDisplay.textContent = counter;
}
renderCounter(counter);

Step 4: Listen for Events

The data is now correctly displayed on the screen, but the buttons have no functionality yet. The next step is to listen for button click events and execute the corresponding functions upon clicking; use eventListener🔗 to listen for “click” events.

// When the + button is clicked, execute addCounter() function
counterAddButton.addEventListener('click', (e) => {
addCounter();
});
// When the Reset button is clicked, execute resetCounter() function
counterResetButton.addEventListener('click', (e) => {
resetCounter();
});
// When the - button is clicked, execute subtractCounter() function
counterMinusButton.addEventListener('click', (e) => {
subtractCounter();
});

In other words, you can achieve the functionality of three eventListeners with a single eventListener by checking the id (e.target.id) of the clicked event target and performing the corresponding action based on that.

counterButtons.addEventListener('click', (e) => {
if (e.target.id === 'add') {
addCounter();
} else if (e.target.id === 'reset') {
resetCounter();
} else if (e.target.id === 'minus') {
subtractCounter();
}
});

Step 5: Manipulating Data

Next, we need to implement the functionality for each button. Here, we define three functions: “add, subtract, and reset.”

// Increase the value of counter and re-render the screen
function addCounter() {
counter++;
renderCounter(counter);
}
// Reset the value of counter and re-render the screen
function resetCounter() {
counter = 0;
renderCounter(counter);
}
// Decrease the value of counter and re-render the screen
function subtractCounter() {
counter--;
renderCounter(counter);
}

Conclusion

From this simple exercise, we have separated data from logic. This separation makes it easier to maintain the code and allows other developers to read and modify it more easily.

This is a simple example, but there are still many things to think about and improve upon, such as: “How can the code be made reusable?” “How can the code be made predictable and testable?” These are all worthwhile questions to consider.

See the Pen Counter by Riceball ( @riecball) on CodePen.