JavaScript Events: Handle Clicks, Input, Forms and User Actions

JavaScript events let your code respond when something happens on a webpage.

A button click can open a menu. Typing in a form can update a character counter. Submitting a form can run validation. Pressing a key can trigger an action.

Events connect user actions with the DOM changes you learned in the previous lesson.

Course Home: JavaScript Tutorial for Beginners
Previous Lesson: JavaScript DOM Manipulation Explained
Next Lesson: JavaScript Form Validation Explained

Quick Answer

JavaScript commonly listens for events with:

addEventListener()

Example:

<button id="button">Click Me</button>
const button = document.querySelector("#button");

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

When the button is clicked, JavaScript runs the function.

Common browser events include:

  • click
  • input
  • change
  • submit
  • keydown
  • keyup
  • focus
  • blur
  • mouseover
  • mouseout

What Is an Event in JavaScript?

An event is something that happens in the browser.

Examples include:

  • A user clicks a button.
  • A user types into an input.
  • A form is submitted.
  • A checkbox changes.
  • A key is pressed.
  • An element receives focus.
  • The mouse moves over an element.
  • The page finishes loading.

JavaScript can listen for these events and run code when they happen.

Why JavaScript Events Matter

Without events, your JavaScript would run only when the script loads or when another part of your code calls a function.

Events let your website respond to users.

They are used for features such as:

  • Mobile menus
  • Dropdowns
  • Accordions
  • Tabs
  • Modal windows
  • Form validation
  • Search suggestions
  • Shopping-cart buttons
  • Quantity controls
  • Image galleries
  • Live counters
  • Keyboard shortcuts
  • Filters
  • Interactive dashboards

Events and JavaScript DOM manipulation work closely together.

The event tells JavaScript when to act.

DOM code decides what changes on the page.

What Is an Event Listener?

An event listener waits for a specific event on an element.

The most common syntax is:

element.addEventListener("eventName", function);

Example:

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

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

Here:

  • button is the element.
  • "click" is the event type.
  • The arrow function is the code that runs after the click.

Basic addEventListener Syntax

A common pattern is:

element.addEventListener("click", () => {
    // code
});

You can also pass a named function:

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

element.addEventListener("click", handleClick);

Notice:

handleClick

has no parentheses when passed to addEventListener().

You are giving the function to the browser so it can call it later.

If this difference is unclear, review the JavaScript Functions tutorial.

JavaScript click Event

The click event runs when a user activates an element with a click.

HTML:

<button id="buyButton">Buy Now</button>

JavaScript:

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

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

The message appears each time the button is clicked.

Real Website Example: Change Text on Click

HTML:

<button id="button">Show Message</button>
<p id="message">Waiting...</p>

JavaScript:

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

button.addEventListener("click", () => {
    message.textContent = "Button clicked";
});

When the user clicks the button, the paragraph changes.

This combines events with DOM manipulation.

Real Website Example: Mobile Menu

HTML:

<button id="menuButton">Menu</button>

<nav id="menu" class="menu">
    <a href="/">Home</a>
    <a href="/about">About</a>
    <a href="/contact">Contact</a>
</nav>

CSS:

.menu {
    display: none;
}

.menu.open {
    display: block;
}

JavaScript:

const menuButton = document.querySelector("#menuButton");
const menu = document.querySelector("#menu");

menuButton.addEventListener("click", () => {
    menu.classList.toggle("open");
});

Each click adds or removes the open class.

This is a common real-world event pattern.

Use a Named Event Handler

Instead of writing the function inside addEventListener(), you can create it separately.

const menuButton = document.querySelector("#menuButton");
const menu = document.querySelector("#menu");

function toggleMenu() {
    menu.classList.toggle("open");
}

menuButton.addEventListener("click", toggleMenu);

A named function can be easier to reuse, test, and remove later.

What Is the Event Object?

When an event happens, the browser creates an event object.

You can receive it as a function parameter.

Example:

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

The event object contains information about what happened.

Common properties include:

event.target
event.currentTarget
event.type

Common methods include:

event.preventDefault()
event.stopPropagation()

event.type

event.type tells you which event occurred.

Example:

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

Output:

click

event.target

event.target is the element where the event originated.

Example:

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

If the button triggered the event, event.target is normally that button.

event.currentTarget

event.currentTarget is the element whose listener is currently running.

Example:

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

For a direct button listener, target and currentTarget may be the same.

They can be different when events bubble from child elements.

You will see that later in this lesson.

target vs currentTarget

Consider:

<button id="button">
    <span>Buy Now</span>
</button>

JavaScript:

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

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

If the user clicks directly on the :

  • event.target may be the .
  • event.currentTarget is the

This difference becomes important in event delegation.

JavaScript input Event

The input event runs when the value of an input changes through user input.

HTML:

<input id="name" type="text">
<p id="preview"></p>

JavaScript:

const nameInput = document.querySelector("#name");
const preview = document.querySelector("#preview");

nameInput.addEventListener("input", () => {
    preview.textContent = nameInput.value;
});

As the user types, the paragraph updates immediately.

Real Website Example: Character Counter

HTML:

<textarea id="message" maxlength="100"></textarea>

<p>
    <span id="count">0</span>/100
</p>

JavaScript:

const message = document.querySelector("#message");
const count = document.querySelector("#count");

message.addEventListener("input", () => {
    count.textContent = message.value.length;
});

The counter updates while the user types.

input vs change Event

input usually runs whenever the value changes through user interaction.

change commonly runs when a value is committed, depending on the form control.

For a text input:

input.addEventListener("input", () => {
    console.log("Input changed");
});

can run on each edit.

The change event often runs later, such as after the field loses focus following a changed value.

For controls such as select menus and checkboxes, change is commonly useful.

JavaScript change Event

HTML:

<select id="category">
    <option value="laptop">Laptop</option>
    <option value="phone">Phone</option>
    <option value="tablet">Tablet</option>
</select>

JavaScript:

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

category.addEventListener("change", () => {
    console.log(category.value);
});

When the user chooses another option, the selected value is printed.

Checkbox change Event

HTML:

<label>
    <input id="terms" type="checkbox">
    Accept terms
</label>

JavaScript:

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

terms.addEventListener("change", () => {
    console.log(terms.checked);
});

The checked property returns a boolean.

JavaScript submit Event

Forms fire a submit event when they are submitted.

HTML:

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

JavaScript:

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

loginForm.addEventListener("submit", (event) => {
    console.log("Form submitted");
});

However, a normal form submission may navigate or reload the page.

To stop that default behavior while you process the form with JavaScript, use:

event.preventDefault();

What Does preventDefault() Do?

preventDefault() stops the browser’s normal action for an event when that action can be canceled.

Example:

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

    console.log("Form handled with JavaScript");
});

The form does not perform its normal submission navigation at that moment.

Your JavaScript can now validate or process the data.

Real Website Example: Basic Form Check

HTML:

<form id="contactForm">
    <input id="email" type="email">
    <button type="submit">Send</button>
</form>

<p id="formMessage"></p>

JavaScript:

const contactForm = document.querySelector("#contactForm");
const email = document.querySelector("#email");
const formMessage = document.querySelector("#formMessage");

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

    if (email.value.trim() === "") {
        formMessage.textContent = "Email is required";
        return;
    }

    formMessage.textContent = "Form ready";
});

This is a simple example.

The next JavaScript Form Validation tutorial will cover validation in detail.

Listen for submit on the Form

A common mistake is listening only for a click on the submit button.

Prefer listening for the form’s:

submit

event.

Why?

A form can be submitted in more than one way, including pressing Enter in a suitable form control.

Use:

form.addEventListener("submit", handleSubmit);

instead of relying only on:

button.addEventListener("click", handleSubmit);

for form submission logic.

JavaScript keydown Event

The keydown event runs when a key is pressed down.

Example:

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

If the user presses Enter, the output is:

Enter

If the user presses Escape:

Escape

Real Website Example: Close Modal With Escape

Suppose:

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

You can listen for Escape:

document.addEventListener("keydown", (event) => {
    if (event.key === "Escape") {
        modal.hidden = true;
    }
});

This is a common keyboard interaction pattern.

A production modal also needs proper focus handling and accessibility behavior.

JavaScript keyup Event

The keyup event runs after a pressed key is released.

Example:

document.addEventListener("keyup", (event) => {
    console.log(`Released: ${event.key}`);
});

Use keydown or keyup based on when your feature needs to respond.

For normal text-field value tracking, the input event is usually better than relying on keyboard events because input can also change through paste, voice input, or other methods.

Keyboard Event Properties

Useful keyboard event properties include:

event.key
event.code
event.ctrlKey
event.shiftKey
event.altKey
event.metaKey

Example:

document.addEventListener("keydown", (event) => {
    if (event.ctrlKey && event.key === "k") {
        console.log("Ctrl + K pressed");
    }
});

Be careful with keyboard shortcuts because browsers and operating systems already use many combinations.

focus Event

The focus event runs when an element receives focus.

HTML:

<input id="email" type="email">

JavaScript:

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

email.addEventListener("focus", () => {
    console.log("Email field focused");
});

Focus events can help with form hints and interactive states.

blur Event

The blur event runs when an element loses focus.

Example:

email.addEventListener("blur", () => {
    console.log("Email field left");
});

A form may use this moment to check whether the value is valid.

Do not rely only on blur validation. Always validate important data again before accepting form submission.

mouseover Event

The mouseover event runs when the pointer enters an element or one of its descendants.

Example:

const card = document.querySelector(".card");

card.addEventListener("mouseover", () => {
    console.log("Pointer is over the card");
});

mouseout Event

mouseout runs when the pointer leaves an element or enters a different descendant context.

Example:

card.addEventListener("mouseout", () => {
    console.log("Pointer left");
});

For many simple hover effects, CSS :hover is a better choice because JavaScript is not needed.

Use JavaScript when the interaction needs logic beyond styling.

mouseenter and mouseleave

You may also see:

mouseenter
mouseleave

These differ from mouseover and mouseout in how they react to descendant elements.

For simple component-level pointer entry and exit, mouseenter and mouseleave can be easier to reason about.

Example:

card.addEventListener("mouseenter", () => {
    console.log("Entered card");
});

dblclick Event

The dblclick event runs after a double-click.

Example:

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

item.addEventListener("dblclick", () => {
    console.log("Double-clicked");
});

Use double-click interactions carefully because they can be less discoverable on websites and may not translate well to touch interfaces.

Event Handler With a Named Function

Example:

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

function handleClick(event) {
    console.log(event.type);
}

button.addEventListener("click", handleClick);

This pattern is useful when:

  • The function is reused
  • The handler contains several lines
  • You need to remove the listener later
  • A clear function name improves readability

Remove an Event Listener

Use:

removeEventListener()

Example:

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

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

button.addEventListener("click", handleClick);

button.removeEventListener("click", handleClick);

The same function reference must be used.

Why Anonymous Functions Are Harder to Remove

This adds a listener:

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

You cannot later remove it by writing a new identical-looking arrow function:

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

Those are two different function objects.

If you know the listener may need to be removed, use a named function or store the function reference.

The once Option

addEventListener() can receive options.

Example:

button.addEventListener(
    "click",
    () => {
        console.log("Runs once");
    },
    { once: true }
);

After the first click, the listener is automatically removed.

This is useful for one-time interactions.

Event Bubbling

Many browser events bubble.

That means an event that starts on a child element can move upward through its ancestors.

Consider:

<div id="card">
    <button id="button">Buy</button>
</div>

JavaScript:

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

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

card.addEventListener("click", () => {
    console.log("Card listener");
});

Clicking the button can print:

Button listener
Card listener

The event starts at the clicked element and bubbles upward.

Why Event Bubbling Matters

Bubbling makes it possible to handle events from many child elements using one listener on a parent.

It also explains why a parent listener may run when you click a child.

Understanding bubbling helps you avoid accidental duplicate behavior.

stopPropagation()

You can stop an event from continuing through the propagation path with:

event.stopPropagation();

Example:

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

    console.log("Button only");
});

Use this carefully.

Stopping propagation can make larger components harder to coordinate if used without a clear reason.

Do not add it automatically to every click handler.

Event Capturing

Events also have a capturing phase before the target phase and bubbling phase.

By default, listeners added with:

addEventListener()

usually handle events during bubbling.

You can opt into capture:

element.addEventListener(
    "click",
    handleClick,
    { capture: true }
);

Beginners do not need capturing for most normal website interactions.

Focus first on standard bubbling behavior.

What Is Event Delegation?

Event delegation means placing one listener on a parent element and handling events from matching child elements.

Suppose your HTML contains:

<ul id="productList">
    <li>
        Laptop
        <button class="remove-button">Remove</button>
    </li>

    <li>
        Phone
        <button class="remove-button">Remove</button>
    </li>
</ul>

Instead of adding one listener to every remove button, you can listen on the list:

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

productList.addEventListener("click", (event) => {
    if (event.target.matches(".remove-button")) {
        console.log("Remove clicked");
    }
});

The click bubbles to the parent.

Why Event Delegation Is Useful

Event delegation can help when:

  • A list contains many repeated buttons.
  • New child elements are added later.
  • You want fewer individual listeners.
  • One parent owns related interactions.

This is especially useful for dynamic product lists, to-do lists, tables, menus, and cards.

Use closest() in Event Delegation

Sometimes the user clicks an element inside the button.

HTML:

<button class="remove-button">
    <span>Remove</span>
</button>

If the is clicked:

event.target

may be the span, not the button.

A robust pattern is:

const button = event.target.closest(".remove-button");

if (!button) {
    return;
}

If needed, also confirm the matched button belongs to the intended container.

You learned closest() in the DOM Manipulation tutorial.

Real Website Example: Remove a List Item With Delegation

HTML:

<ul id="cart">
    <li>
        Keyboard
        <button class="remove-button">Remove</button>
    </li>

    <li>
        Mouse
        <button class="remove-button">Remove</button>
    </li>
</ul>

JavaScript:

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

cart.addEventListener("click", (event) => {
    const removeButton = event.target.closest(".remove-button");

    if (!removeButton) {
        return;
    }

    const item = removeButton.closest("li");

    item?.remove();
});

One listener handles every remove button inside the list.

Real Website Example: Product Quantity Buttons

HTML:

<div class="quantity-control">
    <button id="decrease">-</button>
    <span id="quantity">1</span>
    <button id="increase">+</button>
</div>

JavaScript:

const decreaseButton = document.querySelector("#decrease");
const increaseButton = document.querySelector("#increase");
const quantityText = document.querySelector("#quantity");

let quantity = 1;

increaseButton.addEventListener("click", () => {
    quantity++;
    quantityText.textContent = quantity;
});

decreaseButton.addEventListener("click", () => {
    if (quantity > 1) {
        quantity--;
        quantityText.textContent = quantity;
    }
});

This combines events, variables, conditions, operators, and DOM manipulation.

Real Website Example: Tabs

HTML:

<button class="tab-button" data-tab="details">Details</button>
<button class="tab-button" data-tab="reviews">Reviews</button>

<section id="details">Product details</section>
<section id="reviews" hidden>Customer reviews</section>

JavaScript:

const tabButtons = document.querySelectorAll(".tab-button");
const details = document.querySelector("#details");
const reviews = document.querySelector("#reviews");

for (const button of tabButtons) {
    button.addEventListener("click", () => {
        const selectedTab = button.dataset.tab;

        details.hidden = selectedTab !== "details";
        reviews.hidden = selectedTab !== "reviews";
    });
}

This is a simple two-tab example.

Larger tab components should also manage active states and accessibility attributes.

Real Website Example: Search Preview

HTML:

<input id="search" type="search" placeholder="Search products">

<p id="searchMessage"></p>

JavaScript:

const search = document.querySelector("#search");
const searchMessage = document.querySelector("#searchMessage");

search.addEventListener("input", () => {
    const value = search.value.trim();

    if (value === "") {
        searchMessage.textContent = "Start typing to search";
        return;
    }

    searchMessage.textContent = `Searching for: ${value}`;
});

The message updates as the user types.

Real Website Example: Select Product Size

HTML:

<select id="size">
    <option value="">Choose size</option>
    <option value="S">Small</option>
    <option value="M">Medium</option>
    <option value="L">Large</option>
</select>

<p id="selectedSize"></p>

JavaScript:

const size = document.querySelector("#size");
const selectedSize = document.querySelector("#selectedSize");

size.addEventListener("change", () => {
    if (size.value === "") {
        selectedSize.textContent = "No size selected";
        return;
    }

    selectedSize.textContent = `Selected size: ${size.value}`;
});

Real Website Example: Disable Submit Until Terms Are Checked

HTML:

<label>
    <input id="terms" type="checkbox">
    I accept the terms
</label>

<button id="submitButton" disabled>Submit</button>

JavaScript:

const terms = document.querySelector("#terms");
const submitButton = document.querySelector("#submitButton");

terms.addEventListener("change", () => {
    submitButton.disabled = !terms.checked;
});

The button becomes enabled when the checkbox is checked.

Events on Multiple Elements

Suppose:

<button class="action-button">One</button>
<button class="action-button">Two</button>
<button class="action-button">Three</button>

You can select every button:

const buttons = document.querySelectorAll(".action-button");

Then add listeners:

for (const button of buttons) {
    button.addEventListener("click", () => {
        console.log(button.textContent);
    });
}

This works well for a small static set of elements.

For large or dynamic collections, event delegation can be more convenient.

Inline Event Handlers

You may see HTML like:

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

This works, but it mixes JavaScript behavior into HTML.

For modern projects, prefer:

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

with:

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

button.addEventListener("click", showMessage);

This keeps markup and JavaScript behavior more clearly separated.

addEventListener() vs onclick

You can also write:

button.onclick = handleClick;

However, addEventListener() is generally more flexible.

For example, multiple listeners can be added for the same event:

button.addEventListener("click", firstHandler);
button.addEventListener("click", secondHandler);

Assigning another value to:

button.onclick

replaces the previous property handler.

For this tutorial series, prefer addEventListener().

DOMContentLoaded Event

The browser fires:

DOMContentLoaded

after the HTML document has been parsed.

Example:

document.addEventListener("DOMContentLoaded", () => {
    console.log("DOM ready");
});

If your external script already uses:

<script src="script.js" defer></script>

you often do not need to wrap normal DOM selection code in DOMContentLoaded.

The deferred script runs after HTML parsing is complete.

Review How to Add JavaScript to HTML if you need the loading details.

load Event

The window load event happens after the page and dependent resources such as images have finished loading.

Example:

window.addEventListener("load", () => {
    console.log("Page resources loaded");
});

Do not use load when you only need access to parsed HTML.

Waiting for every resource can delay code unnecessarily.

resize Event

The browser can fire a resize event when the viewport changes size.

Example:

window.addEventListener("resize", () => {
    console.log(window.innerWidth);
});

Resize events can fire many times during resizing.

Avoid expensive work on every event.

Later, you can learn throttling and debouncing for high-frequency events.

scroll Event

The scroll event runs while a document or element is scrolled.

Example:

window.addEventListener("scroll", () => {
    console.log(window.scrollY);
});

Scroll events can fire frequently.

For features such as checking whether an element is visible, APIs such as IntersectionObserver may be a better choice than heavy scroll handlers.

That is a more advanced browser topic.

High-Frequency Events

Some events can fire many times quickly.

Examples include:

  • scroll
  • resize
  • mousemove
  • input

Keep handlers light.

Avoid performing expensive DOM work or large calculations on every event when it is unnecessary.

You will later learn optimization patterns such as debouncing and throttling.

Event Listener Options

addEventListener() can accept an options object.

Common options include:

once
capture
passive
signal

Example:

button.addEventListener(
    "click",
    handleClick,
    {
        once: true
    }
);

Beginners mainly need once at this stage.

The other options become useful for more advanced event handling.

preventDefault() vs stopPropagation()

These methods solve different problems.

preventDefault()

Stops the browser’s default action.

Example:

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

stopPropagation()

Stops the event from continuing through propagation.

Example:

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

Do not use one when you mean the other.

Event Listener and this

Inside a regular function used as a DOM event listener:

button.addEventListener("click", function () {
    console.log(this);
});

this is normally the element whose listener is running.

However, arrow functions do not create their own this:

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

For beginner event code, event.currentTarget is often clearer when you need the element with the listener:

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

Use event.currentTarget for Clear Handler Code

Example:

const buttons = document.querySelectorAll(".action-button");

for (const button of buttons) {
    button.addEventListener("click", (event) => {
        event.currentTarget.classList.add("active");
    });
}

You do not need to depend on arrow-function this behavior.

Common Beginner Mistakes

Calling the Function Instead of Passing It

Wrong when registering a handler:

button.addEventListener("click", handleClick());

This calls the function immediately.

Use:

button.addEventListener("click", handleClick);

Misspelling the Event Name

Wrong:

button.addEventListener("onclick", handleClick);

With addEventListener(), use:

button.addEventListener("click", handleClick);

Do not include on.

Using click Instead of submit for Form Logic

Listening only to the button can miss other valid submission paths.

Prefer:

form.addEventListener("submit", handleSubmit);

Forgetting preventDefault() During JavaScript Form Handling

If you want to process a form without its normal navigation, use:

event.preventDefault();

inside the submit handler.

Do not prevent default behavior unless your JavaScript replaces or manages that action correctly.

Using preventDefault() for Event Bubbling

preventDefault() does not stop bubbling.

Use:

event.stopPropagation();

when propagation truly needs to stop.

Using stopPropagation() Everywhere

Event bubbling is useful.

Stopping it without a reason can break parent interactions and event delegation.

Confusing target and currentTarget

target is where the event originated.

currentTarget is the element whose listener is currently running.

They can be different.

Using keydown to Track Text Changes

Keyboard events do not cover every way an input can change.

For text-value updates, prefer:

input

when appropriate.

Adding Many Listeners When Delegation Is Better

For a small static group, individual listeners are fine.

For a large or dynamic list, one listener on the parent can be simpler.

Using Anonymous Functions When You Need to Remove Them

If a listener must later be removed, keep the same function reference.

Forgetting That Events Can Bubble

A parent click handler may run after a child is clicked.

Check the propagation path before assuming a handler fired twice by mistake.

Using Hover Events for Simple Styling

If the only goal is visual hover styling, CSS is usually the better tool.

Use JavaScript when hover needs real logic.

Heavy Work Inside scroll or resize

These events can fire frequently.

Keep handlers lightweight and use more suitable browser APIs when possible.

Ignoring Keyboard Accessibility

A clickable

is not automatically equivalent to a real button.

Prefer semantic HTML:

<button>Open Menu</button>

instead of adding click behavior to non-interactive elements without proper accessibility support.

Best Practices for JavaScript Events

Use addEventListener() for event handling.

Use semantic HTML controls such as buttons, links, inputs, and forms.

Use named handler functions when reuse or removal is likely.

Use the form submit event for form submission logic.

Use input for live text changes.

Use change for committed value changes when appropriate.

Use event.currentTarget when you need the element whose listener is running.

Understand event.target before building delegated handlers.

Use event delegation for repeated or dynamically added child elements when it simplifies the code.

Use preventDefault() only when you intentionally replace the browser’s default action.

Use stopPropagation() only when stopping propagation is truly required.

Keep high-frequency event handlers light.

Do not use JavaScript for interactions CSS or semantic HTML already handles well.

Keep event handlers focused and move larger logic into separate functions when needed.

Beginner Exercise

Use this HTML:

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

<p id="message">Waiting...</p>

<input id="name" type="text" placeholder="Your name">

<p id="preview"></p>

Complete these tasks:

  1. Listen for a click on the button.
  2. Change the message to Button clicked.
  3. Listen for the input event on the name field.
  4. Show the typed value inside the preview paragraph.
  5. If the field becomes empty, show Type your name.

Try to complete the task using addEventListener().

Challenge Exercise

Use this HTML:

<form id="signupForm">
    <input id="email" type="email" placeholder="Email">
    <input id="password" type="password" placeholder="Password">
    <button type="submit">Sign Up</button>
</form>

<p id="formMessage"></p>

Create a submit listener.

Inside it:

  1. Prevent the normal form submission.
  2. Check whether email is empty.
  3. Check whether password is empty.
  4. Show Complete all fields when either field is empty.
  5. Show Form ready when both fields contain values.

Extra Challenge

Use this HTML:

<ul id="taskList">
    <li>
        Learn HTML
        <button class="remove-button">Remove</button>
    </li>

    <li>
        Learn CSS
        <button class="remove-button">Remove</button>
    </li>

    <li>
        Learn JavaScript
        <button class="remove-button">Remove</button>
    </li>
</ul>

Add only one click listener to:

#taskList

Use event delegation to remove the correct

  • when a remove button is clicked.

    Frequently Asked Questions

    What is an event in JavaScript?

    A JavaScript event is something that happens in the browser, such as a click, form submission, key press, input change, focus change, or page load.

    What is addEventListener()?

    addEventListener() registers a function that should run when a specified event happens.

    Example:

    button.addEventListener("click", handleClick);
    

    What is a click event?

    The click event occurs when a user activates an element with a click.

    What is the input event?

    The input event runs when the value of an editable form control changes through user input.

    It is useful for live previews, counters, and search fields.

    What is the change event?

    The change event runs when a form control’s value is committed or changed, depending on the type of control.

    It is commonly used with select menus and checkboxes.

    What is the submit event?

    The submit event fires on a form when it is submitted.

    Listen on the form rather than only on its submit button.

    What does preventDefault() do?

    event.preventDefault() prevents the browser’s normal default action when that action is cancelable.

    It is commonly used while handling a form submission with JavaScript.

    What is the JavaScript event object?

    The event object contains information about the event.

    Common properties include:

    target
    currentTarget
    type
    key
    

    What is event.target?

    event.target is the element where the event originated.

    What is event.currentTarget?

    event.currentTarget is the element whose event listener is currently running.

    What is event bubbling?

    Event bubbling means many events move from the target element upward through its ancestor elements.

    What is event delegation?

    Event delegation uses a listener on a parent element to handle events from matching child elements.

    It is useful for repeated and dynamically added elements.

    What does stopPropagation() do?

    event.stopPropagation() stops the event from continuing through the propagation path.

    Use it only when that behavior is required.

    What is the difference between preventDefault() and stopPropagation()?

    preventDefault() stops the browser’s default action.

    stopPropagation() stops event propagation through elements.

    They solve different problems.

    What is a keydown event?

    keydown runs when a keyboard key is pressed down.

    You can inspect the pressed key with:

    event.key
    

    What is the difference between keydown and input?

    keydown represents a keyboard action.

    input represents a change to an editable value and can cover changes that do not come only from keyboard presses.

    How do I remove an event listener?

    Use:

    element.removeEventListener("click", handler);
    

    The function reference must match the one used when the listener was added.

    What does { once: true } do?

    It makes the listener run only once and then removes it automatically.

    Should I use onclick or addEventListener()?

    For modern JavaScript, addEventListener() is usually more flexible and keeps event registration separate from HTML.

    Can I add more than one listener to an element?

    Yes.

    addEventListener() can register multiple listeners for the same event.

    What should I learn after JavaScript events?

    Learn JavaScript form validation next. You will use events, DOM manipulation, conditions, and string checks to validate real form fields.

    Summary

    JavaScript events let your code respond to browser and user actions.

    The most common event-listener pattern is:

    element.addEventListener("click", handler);
    

    You learned how to work with:

    • click
    • input
    • change
    • submit
    • keydown
    • keyup
    • focus
    • blur
    • Pointer and mouse events
    • DOMContentLoaded
    • load
    • resize
    • scroll

    You also learned about:

    • The event object
    • event.target
    • event.currentTarget
    • preventDefault()
    • stopPropagation()
    • Event bubbling
    • Event delegation
    • Named event handlers
    • Removing listeners
    • The once option
    • High-frequency events
    • Semantic and accessible interactions

    Events turn static DOM changes into interactive website behavior.

    Continue Learning JavaScript

    Previous Lesson: JavaScript DOM Manipulation Explained

    Course Home: JavaScript Tutorial for Beginners

    Next Lesson: JavaScript Form Validation Explained

    In the next lesson, you will use form events, input values, conditions, strings, and DOM updates to validate required fields, email addresses, passwords, checkboxes, and other common form inputs.

  • James Parker

    James Parker

    James Parker is a technology writer and WordPress enthusiast who shares practical guides on SEO, web development, AI tools, and digital growth. He focuses on creating easy-to-follow tutorials that help beginners and professionals build better websites and improve their online presence.