JavaScript Events: A Refresher + Practical Examples

Learn how JavaScript events work with clear explanations and practical examples. Discover event listeners, propagation, and best practices to make your web pages interactive and responsive.

Published on 05 March 2026
Reading Time 4
Number of Words 703

JavaScript Events: A Refresher + Practical Examples

In JavaScript, events are actions or occurrences (like clicks, key presses, mouse movements, etc.) that happen in the browser and can be handled (i.e., responded to) by your code. By listening to these events, your application can become interactive and dynamic.

Below is a more structured, user-friendly guide to JavaScript events.


Table of Contents

  1. What Are Events?
  2. Event Listeners
  3. Event Objects
  4. Common Event Types
  5. Event Propagation: Capturing & Bubbling
  6. Removing Event Listeners
  7. Useful Patterns & Tips
  8. Full Examples


1. What Are Events?

An event represents something that happens, either triggered by the user (e.g. clicking a button, pressing a key) or by the browser (e.g. page loading, resizing). By attaching a handler (callback) to an event, you tell your code, “When this event happens, do this.”


2. Event Listeners

The most common way to respond to events is via event listeners. The modern standard approach is to use addEventListener:

const button = document.querySelector('#myButton');

button.addEventListener('click', () => {
  alert('Button was clicked!');
});

This attaches an anonymous callback that runs when the click event fires on the button.

You can also use named functions:

function handleClick(event) {
  console.log('Clicked!', event);
}

button.addEventListener('click', handleClick);


3. Event Objects

When an event occurs, the callback receives an event object as the first parameter. This object provides useful information and methods.

Example:

document.addEventListener('keydown', function(event) {
  console.log('Key pressed:', event.key);
  console.log('Was Ctrl pressed too?', event.ctrlKey);
});

Some useful properties and methods of the event object:

  • event.type — the name of the event (e.g. "click", "keydown")
  • event.target — the element on which the event occurred
  • event.currentTarget — the element to which the event handler is attached
  • event.preventDefault() — prevent default browser behavior (e.g. following a link)
  • event.stopPropagation() — stop further propagation of the event


4. Common Event Types

Here are some frequently used event types:

Event Type When It Fires Example Use
click When an element is clicked Buttons, links
submit When a form is submitted Form validation
keydown / keyup When a key is pressed / released Keyboard shortcuts
input / change When user enters data, or element’s value changes Real-time validation
DOMContentLoaded When initial HTML is fully loaded Initialize scripts after DOM is ready
scroll When user scrolls on an element or page Infinite scroll, animations
resize When the browser window is resized Responsive layout adjustments

Example:

window.addEventListener('resize', function(event) {
  console.log('Window resized to:', window.innerWidth, window.innerHeight);
});


5. Event Propagation: Capturing & Bubbling

When an event happens, it doesn’t just act on the target element — it traverses the DOM in phases:

  • Capturing phase — the event moves from the top (document) down to the target.
  • Target phase — the event occurs at the target element itself.
  • Bubbling phase — the event bubbles upward from the target back up to the top.

By default, event listeners respond during the bubbling phase. But you can optionally listen during the capturing phase:

element.addEventListener('click', callback, { capture: true });

You can also stop propagation to prevent parent handlers from being triggered:

element.addEventListener('click', function(event) {
  event.stopPropagation();
  // Parent click handlers won’t run
});


6. Removing Event Listeners

To clean up or avoid memory leaks, you may want to remove an event listener when it is no longer needed:

button.removeEventListener('click', handleClick);

Important: The function reference passed to removeEventListener must exactly match the reference used in addEventListener. Anonymous functions can’t be removed easily.


7. Useful Patterns & Tips

  • Event delegation: Instead of attaching event listeners to many child elements, attach one listener to a parent and check event.target. This is efficient and works dynamically for future child elements. listContainer.addEventListener('click', function(event) { if (event.target.tagName === 'LI') { console.log('Clicked item:', event.target.textContent); } });
  • Throttling / debouncing: For performance-intensive events like scroll or resize, use throttling or debouncing to limit how often handlers run.
  • Once option: You can pass { once: true } when adding a listener to have it automatically removed after its first invocation: button.addEventListener('click', () => { alert('Done!'); }, { once: true });
  • Passive listeners: Use { passive: true } for listeners (especially scroll, touch) to hint the browser that you won’t call preventDefault(), improving performance.


8. Full Examples

Example 1: Form Validation

const form = document.querySelector('#signupForm');

form.addEventListener('submit', function(event) {
  const emailInput = event.target.querySelector('input[name="email"]');
  if (!emailInput.value.includes('@')) {
    event.preventDefault();
    alert('Please enter a valid email address.');
  }
});

Example 2: Toggle a CSS Class on Click

const btn = document.getElementById('toggleBtn');
const box = document.getElementById('box');

btn.addEventListener('click', () => {
  box.classList.toggle('active');
});

Example 3: Delegated Clicks Within a List

const list = document.getElementById('todoList');

list.addEventListener('click', (event) => {
  if (event.target.matches('.delete-btn')) {
    const li = event.target.closest('li');
    li.remove();
  }
});

Example 4: Resize with Debouncing

let resizeTimeout;

window.addEventListener('resize', () => {
  clearTimeout(resizeTimeout);
  resizeTimeout = setTimeout(() => {
    console.log('Resized to:', window.innerWidth, window.innerHeight);
  }, 200);
});