How to use JavaScript to make a web page interactive

Before starting, make sure you have completed the previous sections, especially 1. First steps 🧑‍🎓, 2. Pushing further 🚀, and the lessons on HTML and CSS.

JavaScript was created in 1995 by Brendan Eich. Since then, the language has evolved but has continued to power the web. It wasn’t until 2012 that TypeScript appeared, adding features like types to JavaScript. TypeScript is called a superset of JavaScript.

However, browsers still run JavaScript. They don’t understand TypeScript. This is why modern web development toolsets transpile TypeScript into JavaScript.

In this lesson, we won’t use any tooling. We’ll run JavaScript code directly in the browser. Don’t worry: by now, you know TypeScript, so JavaScript will be a piece of cake. It’s the same, just without the types!

Want to know when new lessons are available? Subscribe to the newsletter ✉ and give a ⭐ to the GitHub repository to keep me motivated! Click here to get in touch.

Setup

We don’t need to install anything new, but we will work with the code from the previous lesson.

Open an empty folder in VS Code. Download this picture from my Google Drive and place it in your project. Then, copy and paste the code below into a new index.html.

index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My Alma Mater</title>
    <link rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css">
</head>
<body>
    <h1>My Alma Mater: UQAM</h1>
    <p>I earned my bachelor's degree in journalism at Université du Québec à Montréal (UQAM).</p>
    <img src="university.jpg" alt="UQAM campus with Montreal’s downtown skyline in the background."/>
    <p>The picture above comes from Wikimedia. You can find it <a href="https://commons.wikimedia.org/wiki/File:UQAM-Judith-Jasmin.jpg">here</a> along with its license.</p>
    <p>Montreal is a wonderful city. You should visit it!</p>
</body>
</html>

Une capture d’écran montrant la console du navigateur et VS Code avec du code.

Creating a .js file

While you can write JavaScript directly in the HTML using <script> and </script> tags, it’s usually best to isolate your JavaScript in one or more .js files. This will make your code easier to maintain in the long run.

Let’s create a new file called main.js with a simple console.log in it.

main.js
console.log("Hi!");

To run this code in your webpage, you need to import it into your HTML. Below, we specify the defer attribute so that our JavaScript code will be executed once the entire page is ready. This is important if you want to modify or interact with the content of the page, as we do. If your script runs too soon and the elements have not yet been created by the browser, you’ll get an error.

However, sometimes you don’t need the page elements. If you want your script to run as soon as possible, you can specify the async attribute instead of defer.

index.html
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>My Alma Mater</title>
        <link rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css">
        <script src="main.js" defer></script>
    </head>
    <body>
        <h1>My Alma Mater: UQAM</h1>
        <p>
            I earned my bachelor's degree in journalism at Université du Québec
            à Montréal (UQAM).
        </p>
        <img
            src="university.jpg"
            alt="UQAM campus with Montreal’s downtown skyline in the background."
        />
        <p>
            The picture above comes from Wikimedia. You can find it <a
                href="https://commons.wikimedia.org/wiki/File:UQAM-Judith-Jasmin.jpg"
            >here</a> along with its license.
        </p>
        <p>
            Montreal is a wonderful city. You should visit it!
        </p>
    </body>
</html>

To check if our code runs on the page, we can refresh and check the console.

When we ran TypeScript with Deno, console.log displayed information in the terminal. But now that we are working on a web page, this information is displayed in the browser’s console.

You should see Hi! in the console, indicating that our code runs every time the page is loaded!

A screenshot showing the browser's console and VS Code with some code.

Event listeners

When you want the user to interact with your page, you first need to select the element to be interacted with, then add one or more event listeners. To select elements, you can use selectors just like you would in CSS.

For a concrete example, let’s create a button that can be clicked to change the body color. In index.html, we add the button with the id change-background.

index.html
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>My Alma Mater</title>
        <link rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css">
        <script src="main.js" defer></script>
    </head>
    <body>
        <h1>My Alma Mater: UQAM</h1>
        <p>
            I earned my bachelor's degree in journalism at Université du Québec
            à Montréal (UQAM).
        </p>
        <img
            src="university.jpg"
            alt="UQAM campus with Montreal’s downtown skyline in the background."
        />
        <p>
            The picture above comes from Wikimedia. You can find it <a
                href="https://commons.wikimedia.org/wiki/File:UQAM-Judith-Jasmin.jpg"
            >here</a> along with its license.
        </p>
        <p>
            Montreal is a wonderful city. You should visit it!
        </p>
        <button id="change-background">
            Click me to change the background color!
        </button>
    </body>
</html>

Now, let’s update main.js:

  • First, we create an array of randomColors (lines 1–12).
  • Then, we select our button using document.querySelector with the selector #change-background (line 14). Here, we want to select a single button, but to select multiple elements you can use querySelectorAll.
  • We add a click event listener to our button with addEventListener("click", ...) (line 16).
  • The second argument of addEventListener is a function triggered when the user interacts with the element. Here, we pick a random color and apply it as the background for the page’s body (lines 17–20).

When the page loads, our code looks for the button and then waits for the user to interact with it.

main.js
const randomColors = [
    "red",
    "blue",
    "green",
    "yellow",
    "pink",
    "purple",
    "orange",
    "brown",
    "gray",
    "white",
];
 
const button = document.querySelector("#change-background");
 
button.addEventListener("click", () => {
    const randomIndex = Math.floor(Math.random() * randomColors.length);
    const randomColor = randomColors[randomIndex];
 
    document.body.style.backgroundColor = randomColor;
});

A screenshot showing event listeners code in VS Code.

💡

When reading other online tutorials, you might hear about the DOM (Document Object Model). It’s the JavaScript representation of the HTML. When you select an HTML element in JavaScript, you select it from the DOM.

There are many different types of listeners, and you can also remove them with the removeEventListener method. However, make sure to use a named function instead of an arrow function like above; otherwise, it won’t work.

Conclusion

Congratulations! You just made your page interactive! Of course, the interaction here is quite basic, but the same principles can be applied to complex interactive data visualizations: when the user interacts with the page, you update what is being shown.

You could also use fetch to retrieve different data files and create various charts based on user choices. Or you could fetch fresh data every 15 seconds with setInterval and redraw charts, like we do for election dashboards. By the way, fetch in Deno works the same way as fetch in the browser. 😊

There are also more specialized APIs, like the Intersection Observer API, to monitor how far the user scrolls and trigger animations—like we do in scrolly-telling projects such as this one. (I know the word “API” can be confusing here since we’ve used APIs mainly for retrieving data so far, but an API can be anything—not just for data. This one is more like a function.)

I kept this lesson very simple since it’s your first time coding JavaScript for the web, and we are quite limited because we haven’t run a local server. But I think you’re now ready for the next step!

Enjoyed this? Want to know when new lessons are available? Subscribe to the newsletter ✉ and give a ⭐ to the GitHub repository to keep me motivated! Get in touch if you have any questions.