Chapter 26 of 31

JavaScript DOM Events

In the previous topic, we learned how JavaScript can manipulate the DOM—changing text, styles, attributes, and even creating or removing elements.

But there's another important question:

How does JavaScript know that something happened on the webpage?

For example:

  • A user clicked a button.

  • They typed something into an input.

  • The mouse moved over an element.

  • A form was submitted.

  • The webpage finished loading.

These actions are called events.

What is a DOM Event?

A DOM event is an action or occurrence that happens in the browser and can be detected and handled using JavaScript.

For example, when a user clicks a button, the browser generates a click event.

JavaScript can listen for that event and run some code.

User performs an action
        ↓
Browser detects the event
        ↓
JavaScript listens for it
        ↓
Event handler runs

This is what allows webpages to become interactive.


The addEventListener() Method

The most common way to handle DOM events is addEventListener().

Syntax

element.addEventListener("event", function);

For example, suppose we have:

<button id="btn">Click Me</button>

We can listen for a click:

const button = document.querySelector("#btn");

button.addEventListener("click", () => {
    console.log("Button clicked!");
});

Now every time the user clicks the button, the message is printed.


Common DOM Events

JavaScript supports many different events.

Event

Happens when...

click

An element is clicked

dblclick

An element is double-clicked

mousedown

Mouse button is pressed

mouseup

Mouse button is released

mousemove

Mouse moves

mouseenter

Mouse enters an element

mouseleave

Mouse leaves an element

keydown

A keyboard key is pressed

keyup

A keyboard key is released

input

Input value changes

change

An input's committed value changes

focus

An element receives focus

blur

An element loses focus

submit

A form is submitted

DOMContentLoaded

HTML document has been loaded and parsed

Let's look at some of the important ones.


Click Event

The click event is probably the first event you'll use.

HTML:

<button id="btn">Click Me</button>

JavaScript:

const button = document.querySelector("#btn");

button.addEventListener("click", () => {
    console.log("You clicked the button!");
});

Every click triggers the function.


Changing the Page on Click

Events become more useful when we combine them with DOM manipulation.

HTML:

<h1 id="title">Hello World</h1>
<button id="btn">Change Text</button>

JavaScript:

const title = document.querySelector("#title");
const button = document.querySelector("#btn");

button.addEventListener("click", () => {
    title.textContent = "Text Changed!";
});

Now clicking the button changes the heading.

This is the basic pattern behind many interactive web features:

Event → JavaScript logic → DOM update

Keyboard Events

We can also detect keyboard actions.

For example:

document.addEventListener("keydown", (event) => {
    console.log("Key pressed:", event.key);
});

If the user presses the A key, we might get:

Key pressed: a

The event object gives us information about what happened.

For example:

document.addEventListener("keydown", (event) => {
    if (event.key === "Enter") {
        console.log("Enter was pressed!");
    }
});

This can be useful for keyboard shortcuts, search boxes, games, and form handling.


The Event Object

When an event occurs, the browser provides information about that event.

We can receive it as a parameter:

button.addEventListener("click", (event) => {
    console.log(event);
});

This event object contains useful information about what happened.

For example:

button.addEventListener("click", (event) => {
    console.log(event.type);
});

Output:

click

We can also find the element that triggered the event:

button.addEventListener("click", (event) => {
    console.log(event.target);
});

event.target refers to the element that actually triggered the event.


Input Events

Suppose we have an input field:

<input id="username" type="text">

We can detect whenever its value changes:

const input = document.querySelector("#username");

input.addEventListener("input", (event) => {
    console.log(event.target.value);
});

If the user types:

John

the handler runs as the value changes.

This is useful for live search, validation, character counters, and similar features.


Form Submit Event

Forms are another important place where events are used.

HTML:

<form id="loginForm">
    <input type="text" id="username">
    <button type="submit">Login</button>
</form>

JavaScript:

const form = document.querySelector("#loginForm");

form.addEventListener("submit", (event) => {
    event.preventDefault();

    console.log("Form submitted!");
});

What does preventDefault() do?

Normally, submitting a form may cause the browser to navigate or reload the page.

event.preventDefault();

prevents that default browser behavior.

This is very useful when you want JavaScript to handle the form submission yourself.


Mouse Events

We can respond to mouse interactions too.

For example:

const box = document.querySelector("#box");

box.addEventListener("mouseenter", () => {
    console.log("Mouse entered the box");
});

box.addEventListener("mouseleave", () => {
    console.log("Mouse left the box");
});

This can be used for things like tooltips, menus, hover effects, and interactive components.


Adding Multiple Event Listeners

An element can have multiple listeners for the same or different events.

button.addEventListener("click", () => {
    console.log("First handler");
});

button.addEventListener("click", () => {
    console.log("Second handler");
});

When the button is clicked, both handlers can run.


Removing an Event Listener

We can remove an event listener using removeEventListener().

However, there's an important detail: we need to provide the same function reference that was used when adding the listener.

function handleClick() {
    console.log("Clicked!");
}

button.addEventListener("click", handleClick);

button.removeEventListener("click", handleClick);

After removing it, clicking the button will no longer trigger handleClick.

This won't work as expected:

button.addEventListener("click", () => {
    console.log("Clicked!");
});

button.removeEventListener("click", () => {
    console.log("Clicked!");
});

These are two different function objects, even though their code looks identical.


Event Delegation

When working with many elements, we don't always need to add an event listener to every single element.

Instead, we can listen on a parent element and use event delegation.

For example:

<ul id="list">
    <li>Apple</li>
    <li>Banana</li>
    <li>Mango</li>
</ul>

Instead of adding a listener to every <li>:

const list = document.querySelector("#list");

list.addEventListener("click", (event) => {
    if (event.target.matches("li")) {
        console.log(event.target.textContent);
    }
});

Now the parent <ul> handles clicks from its list items.

This becomes especially useful when elements are added dynamically.


Event Bubbling

One important concept behind event delegation is event bubbling.

Suppose we have:

<div id="parent">
    <button id="child">Click Me</button>
</div>

If we click the button, the event can first occur on the button and then bubble upward through its ancestors.

Conceptually:

button
   ↑
div
   ↑
body
   ↑
document

For example:

const parent = document.querySelector("#parent");
const child = document.querySelector("#child");

parent.addEventListener("click", () => {
    console.log("Parent clicked");
});

child.addEventListener("click", () => {
    console.log("Child clicked");
});

Clicking the button can produce:

Child clicked
Parent clicked

because the click event bubbles from the button to the parent.


Stopping Event Propagation

Sometimes we don't want an event to continue bubbling.

We can use:

event.stopPropagation();

For example:

child.addEventListener("click", (event) => {
    event.stopPropagation();

    console.log("Child clicked");
});

Now the click won't continue bubbling to the parent listener.


DOM Events vs Inline Events

You may sometimes see event handlers directly inside HTML:

<button onclick="sayHello()">Click Me</button>

Although this can work, using addEventListener() is generally preferred:

button.addEventListener("click", sayHello);

It keeps your HTML structure and JavaScript logic separate, which makes larger applications easier to maintain.


A Practical Example

Let's create a simple counter using DOM events.

HTML:

<h2 id="count">0</h2>

<button id="increase">Increase</button>
<button id="decrease">Decrease</button>

JavaScript:

const count = document.querySelector("#count");
const increase = document.querySelector("#increase");
const decrease = document.querySelector("#decrease");

let value = 0;

increase.addEventListener("click", () => {
    value++;
    count.textContent = value;
});

decrease.addEventListener("click", () => {
    value--;
    count.textContent = value;
});

Now the buttons actually interact with the webpage:

0
↓ Increase
1
↓ Increase
2
↓ Decrease
1

This small example combines several concepts we've already learned:

  • Variables

  • Functions

  • Arrow functions

  • DOM selection

  • textContent

  • Event listeners

Conclusion

DOM events are what make webpages interactive.

The most important concept is:

element.addEventListener("event", handler);

For example:

button.addEventListener("click", () => {
    console.log("Button clicked!");
});

Remember these important ideas:

  • Event → Something happens in the browser.

  • Event listener → JavaScript waits for that event.

  • Event handler → Code that runs when the event occurs.

  • Event object → Contains information about the event.

  • preventDefault() → Stops the browser's default behavior.

  • stopPropagation() → Stops the event from propagating further.

  • Event delegation → Handle events from child elements using a parent.

Once you understand DOM events, you can start building genuinely interactive features such as forms, menus, buttons, modals, live search, counters, dropdowns, and interactive UI components.