Docs

README

10.3 Events and Event Handling

πŸ“š Learning Objectives

By the end of this section, you will:

  • β€’Understand the event system in the browser
  • β€’Add and remove event listeners
  • β€’Work with the event object and its properties
  • β€’Understand event propagation (bubbling and capturing)
  • β€’Prevent default behaviors and stop propagation
  • β€’Handle common event types

πŸ“– Table of Contents

  1. β€’Understanding Events
  2. β€’Adding Event Listeners
  3. β€’The Event Object
  4. β€’Event Propagation
  5. β€’Controlling Event Behavior
  6. β€’Common Event Types

Understanding Events

What are Events?

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    Browser Event System                          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                  β”‚
β”‚  User Action          Browser                   Your Code        β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”‚
β”‚  β”‚  Click   │───────▢│  Event   │─────────────▢│ Handler  β”‚     β”‚
β”‚  β”‚  Type    β”‚        β”‚ Created  β”‚              β”‚ Function β”‚     β”‚
β”‚  β”‚  Scroll  β”‚        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚
β”‚  β”‚  etc.    β”‚                                                    β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                                    β”‚
β”‚                                                                  β”‚
β”‚  Events can be triggered by:                                     β”‚
β”‚  β€’ User interactions (click, type, scroll)                       β”‚
β”‚  β€’ Browser actions (load, resize, error)                         β”‚
β”‚  β€’ API/Code (custom events)                                      β”‚
β”‚                                                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Event Categories

CategoryEventsDescription
Mouseclick, dblclick, mousedown, mouseup, mousemove, mouseenter, mouseleaveUser mouse interactions
Keyboardkeydown, keyup, keypress (deprecated)Keyboard input
Formsubmit, change, input, focus, blurForm interactions
DocumentDOMContentLoaded, load, beforeunloadPage lifecycle
Windowresize, scroll, hashchangeBrowser window
Touchtouchstart, touchmove, touchendMobile touch

Adding Event Listeners

addEventListener Method

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    addEventListener Syntax                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                  β”‚
β”‚  element.addEventListener(type, handler, options)                β”‚
β”‚                           β”‚     β”‚        β”‚                       β”‚
β”‚                           β”‚     β”‚        └─ Optional config      β”‚
β”‚                           β”‚     └─ Function to call              β”‚
β”‚                           └─ Event name (string)                 β”‚
β”‚                                                                  β”‚
β”‚  Options object:                                                 β”‚
β”‚  {                                                               β”‚
β”‚      capture: false,    // Use capture phase                     β”‚
β”‚      once: false,       // Remove after first call               β”‚
β”‚      passive: false     // Never call preventDefault             β”‚
β”‚  }                                                               β”‚
β”‚                                                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Basic Event Listener

const button = document.getElementById('myButton');

// Method 1: Named function
function handleClick(event) {
  console.log('Button clicked!', event);
}
button.addEventListener('click', handleClick);

// Method 2: Anonymous function
button.addEventListener('click', function (event) {
  console.log('Clicked!');
});

// Method 3: Arrow function
button.addEventListener('click', (event) => {
  console.log('Arrow function handler');
});

Removing Event Listeners

const button = document.getElementById('myButton');

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

// Add listener
button.addEventListener('click', handleClick);

// Remove listener (must use same function reference)
button.removeEventListener('click', handleClick);

// ❌ This won't work - different function references
button.addEventListener('click', function () {
  console.log('A');
});
button.removeEventListener('click', function () {
  console.log('A');
});

Using Options

const button = document.getElementById('myButton');

// Run only once
button.addEventListener(
  'click',
  () => {
    console.log('This runs only once!');
  },
  { once: true }
);

// Passive listener (for performance in scroll/touch)
window.addEventListener('scroll', handleScroll, { passive: true });

// Capture phase listener
element.addEventListener('click', handler, { capture: true });
// OR shorthand:
element.addEventListener('click', handler, true);

Old Way vs Modern Way

// ❌ Old ways (avoid)
button.onclick = function() { };  // Only one handler possible
<button onclick="handler()">      // Inline (avoid)

// βœ“ Modern way (recommended)
button.addEventListener("click", handler);  // Multiple handlers OK

The Event Object

Event Object Properties

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    Event Object Properties                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                  β”‚
β”‚  General Properties:                                             β”‚
β”‚  β”œβ”€β”€ type           β†’ Event type ("click", "keydown", etc.)      β”‚
β”‚  β”œβ”€β”€ target         β†’ Element that triggered the event           β”‚
β”‚  β”œβ”€β”€ currentTarget  β†’ Element handler is attached to             β”‚
β”‚  β”œβ”€β”€ timeStamp      β†’ When event was created                     β”‚
β”‚  └── isTrusted      β†’ User action (true) or script (false)       β”‚
β”‚                                                                  β”‚
β”‚  Mouse Event Properties:                                         β”‚
β”‚  β”œβ”€β”€ clientX/Y      β†’ Coordinates relative to viewport           β”‚
β”‚  β”œβ”€β”€ pageX/Y        β†’ Coordinates relative to document           β”‚
β”‚  β”œβ”€β”€ offsetX/Y      β†’ Coordinates relative to target element     β”‚
β”‚  β”œβ”€β”€ screenX/Y      β†’ Coordinates relative to screen             β”‚
β”‚  β”œβ”€β”€ button         β†’ Which mouse button (0, 1, 2)               β”‚
β”‚  └── buttons        β†’ Pressed buttons (bitfield)                 β”‚
β”‚                                                                  β”‚
β”‚  Keyboard Event Properties:                                      β”‚
β”‚  β”œβ”€β”€ key            β†’ Key value ("a", "Enter", "ArrowUp")        β”‚
β”‚  β”œβ”€β”€ code           β†’ Physical key ("KeyA", "Enter")             β”‚
β”‚  β”œβ”€β”€ altKey         β†’ Alt key pressed?                           β”‚
β”‚  β”œβ”€β”€ ctrlKey        β†’ Ctrl key pressed?                          β”‚
β”‚  β”œβ”€β”€ shiftKey       β†’ Shift key pressed?                         β”‚
β”‚  └── metaKey        β†’ Meta (Cmd/Win) key pressed?                β”‚
β”‚                                                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Using Event Properties

// Mouse event example
element.addEventListener('click', (event) => {
  console.log('Event type:', event.type);
  console.log('Target element:', event.target);
  console.log('Current target:', event.currentTarget);
  console.log('Viewport position:', event.clientX, event.clientY);
  console.log('Page position:', event.pageX, event.pageY);
});

// Keyboard event example
document.addEventListener('keydown', (event) => {
  console.log('Key pressed:', event.key);
  console.log('Key code:', event.code);
  console.log('Shift held:', event.shiftKey);
  console.log('Ctrl held:', event.ctrlKey);

  // Check for keyboard shortcuts
  if (event.ctrlKey && event.key === 's') {
    event.preventDefault();
    console.log('Ctrl+S pressed');
  }
});

target vs currentTarget

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                  target vs currentTarget                          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                  β”‚
β”‚  HTML:                                                           β”‚
β”‚  <div id="parent">                                               β”‚
β”‚      <button id="child">Click</button>                           β”‚
β”‚  </div>                                                          β”‚
β”‚                                                                  β”‚
β”‚  JavaScript:                                                     β”‚
β”‚  parent.addEventListener("click", (e) => {                       β”‚
β”‚      console.log(e.target);        // <button> (clicked element) β”‚
β”‚      console.log(e.currentTarget); // <div> (listener element)   β”‚
β”‚  });                                                             β”‚
β”‚                                                                  β”‚
β”‚  When clicking the button:                                       β”‚
β”‚  β€’ target = button (what you clicked)                            β”‚
β”‚  β€’ currentTarget = div (where listener is attached)              β”‚
β”‚                                                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Event Propagation

Phases of Event Propagation

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    Event Propagation Phases                          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                     β”‚
β”‚           β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                β”‚
β”‚           β”‚              Document                   β”‚                β”‚
β”‚           β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚                β”‚
β”‚           β”‚  β”‚              <html>               β”‚  β”‚                β”‚
β”‚           β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚  β”‚                β”‚
β”‚           β”‚  β”‚  β”‚           <body>            β”‚  β”‚  β”‚                β”‚
β”‚           β”‚  β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚  β”‚  β”‚                β”‚
β”‚           β”‚  β”‚  β”‚  β”‚        <div>         β”‚  β”‚  β”‚  β”‚                β”‚
β”‚           β”‚  β”‚  β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚  β”‚  β”‚  β”‚                β”‚
β”‚           β”‚  β”‚  β”‚  β”‚  β”‚   <button>   β”‚   β”‚  β”‚  β”‚  β”‚                β”‚
β”‚    1      β”‚  β”‚  β”‚  β”‚  β”‚    CLICK!    β”‚   β”‚  β”‚  β”‚  β”‚     3          β”‚
β”‚ Capture   β”‚  β”‚  β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚  β”‚  β”‚  β”‚  Bubble        β”‚
β”‚   Down    β”‚  β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚  β”‚  β”‚    Up          β”‚
β”‚    ↓      β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚  β”‚    ↑           β”‚
β”‚           β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚                β”‚
β”‚           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                β”‚
β”‚                                                                     β”‚
β”‚  Phase 1: CAPTURING - Event travels DOWN from window to target      β”‚
β”‚  Phase 2: TARGET - Event reaches the target element                 β”‚
β”‚  Phase 3: BUBBLING - Event travels UP from target to window         β”‚
β”‚                                                                     β”‚
β”‚  By default, handlers run in BUBBLING phase                         β”‚
β”‚  Use { capture: true } to run in CAPTURING phase                    β”‚
β”‚                                                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Bubbling Example

// HTML: <div><p><span>Click me</span></p></div>

document.querySelector('span').addEventListener('click', () => {
  console.log('1. span clicked'); // Runs first
});

document.querySelector('p').addEventListener('click', () => {
  console.log('2. p clicked'); // Runs second
});

document.querySelector('div').addEventListener('click', () => {
  console.log('3. div clicked'); // Runs third
});

// Clicking the span outputs:
// 1. span clicked
// 2. p clicked
// 3. div clicked

Capturing Example

// Add listeners in capture phase
document.querySelector('div').addEventListener(
  'click',
  () => {
    console.log('1. div (capture)');
  },
  true
); // capture: true

document.querySelector('p').addEventListener(
  'click',
  () => {
    console.log('2. p (capture)');
  },
  true
);

document.querySelector('span').addEventListener('click', () => {
  console.log('3. span (target)');
});

// Clicking the span outputs:
// 1. div (capture)    - capture phase
// 2. p (capture)      - capture phase
// 3. span (target)    - target phase

Controlling Event Behavior

preventDefault()

// Prevent default link behavior
link.addEventListener('click', (event) => {
  event.preventDefault();
  console.log('Link click prevented');
});

// Prevent form submission
form.addEventListener('submit', (event) => {
  event.preventDefault();
  console.log('Form submission prevented');
  // Handle form data with JavaScript instead
});

// Prevent right-click context menu
element.addEventListener('contextmenu', (event) => {
  event.preventDefault();
  showCustomMenu(event.clientX, event.clientY);
});

stopPropagation()

// Prevent event from bubbling up
innerElement.addEventListener('click', (event) => {
  event.stopPropagation();
  console.log("Click handled here, won't bubble");
});

// Outer handler won't run if inner calls stopPropagation
outerElement.addEventListener('click', () => {
  console.log("This won't run if inner element is clicked");
});

stopImmediatePropagation()

// Stop all other handlers, even on same element
element.addEventListener('click', (event) => {
  console.log('Handler 1');
  event.stopImmediatePropagation();
});

element.addEventListener('click', () => {
  console.log("Handler 2 - won't run!");
});

Comparison Table

MethodStops BubblingStops Other Handlers on Same ElementStops Default Behavior
preventDefault()βŒβŒβœ…
stopPropagation()βœ…βŒβŒ
stopImmediatePropagation()βœ…βœ…βŒ

Common Event Types

Mouse Events

const element = document.getElementById('target');

// Click events
element.addEventListener('click', (e) => console.log('Single click'));
element.addEventListener('dblclick', (e) => console.log('Double click'));

// Mouse button events
element.addEventListener('mousedown', (e) => console.log('Mouse button down'));
element.addEventListener('mouseup', (e) => console.log('Mouse button up'));

// Mouse movement
element.addEventListener('mousemove', (e) => {
  console.log(`Mouse at: ${e.clientX}, ${e.clientY}`);
});

// Enter/leave (don't bubble)
element.addEventListener('mouseenter', (e) => console.log('Mouse entered'));
element.addEventListener('mouseleave', (e) => console.log('Mouse left'));

// Over/out (bubble)
element.addEventListener('mouseover', (e) => console.log('Mouse over'));
element.addEventListener('mouseout', (e) => console.log('Mouse out'));

Keyboard Events

// Modern keyboard handling
document.addEventListener('keydown', (event) => {
  // Use event.key for character
  console.log('Key:', event.key);

  // Use event.code for physical key
  console.log('Code:', event.code);

  // Common checks
  if (event.key === 'Enter') {
    console.log('Enter pressed');
  }

  if (event.key === 'Escape') {
    console.log('Escape pressed');
  }

  // Arrow keys
  if (event.key.startsWith('Arrow')) {
    console.log('Arrow key:', event.key);
  }

  // Keyboard shortcuts
  if (event.ctrlKey && event.key === 's') {
    event.preventDefault();
    saveDocument();
  }
});

document.addEventListener('keyup', (event) => {
  console.log('Key released:', event.key);
});

Form Events

const form = document.getElementById('myForm');
const input = document.getElementById('email');

// Form submission
form.addEventListener('submit', (event) => {
  event.preventDefault();
  const formData = new FormData(form);
  console.log('Form submitted:', Object.fromEntries(formData));
});

// Input events
input.addEventListener('input', (event) => {
  console.log('Value changed:', event.target.value);
});

input.addEventListener('change', (event) => {
  console.log('Input changed (on blur):', event.target.value);
});

// Focus events
input.addEventListener('focus', () => console.log('Input focused'));
input.addEventListener('blur', () => console.log('Input blurred'));

Window/Document Events

// Page load
window.addEventListener('DOMContentLoaded', () => {
  console.log('DOM ready (HTML parsed)');
});

window.addEventListener('load', () => {
  console.log('Page fully loaded (including images)');
});

// Before leaving page
window.addEventListener('beforeunload', (event) => {
  event.preventDefault();
  event.returnValue = ''; // Show confirmation dialog
});

// Window resize
window.addEventListener('resize', () => {
  console.log('Window size:', window.innerWidth, window.innerHeight);
});

// Scroll
window.addEventListener('scroll', () => {
  console.log('Scroll position:', window.scrollY);
});

Event Flow Summary

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        Event Handling Summary                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                     β”‚
β”‚  Adding Listeners:                                                  β”‚
β”‚  β€’ element.addEventListener(type, handler)     // Standard          β”‚
β”‚  β€’ element.addEventListener(type, handler, options)  // With optionsβ”‚
β”‚                                                                     β”‚
β”‚  Removing Listeners:                                                β”‚
β”‚  β€’ element.removeEventListener(type, handler)  // Same reference!   β”‚
β”‚                                                                     β”‚
β”‚  Event Object:                                                      β”‚
β”‚  β€’ e.target         - Element that triggered event                  β”‚
β”‚  β€’ e.currentTarget  - Element with the listener                     β”‚
β”‚  β€’ e.type           - Event type string                             β”‚
β”‚  β€’ e.preventDefault()      - Stop default action                    β”‚
β”‚  β€’ e.stopPropagation()     - Stop bubbling                          β”‚
β”‚                                                                     β”‚
β”‚  Propagation:                                                       β”‚
β”‚  β€’ Capture β†’ Target β†’ Bubble                                        β”‚
β”‚  β€’ Default handlers run in bubble phase                             β”‚
β”‚  β€’ Use { capture: true } for capture phase                          β”‚
β”‚                                                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ’‘ Key Takeaways

  1. β€’Use addEventListener: Always prefer addEventListener over inline handlers
  2. β€’Save Function References: To remove listeners, you need the same function reference
  3. β€’Use Event Object: Access event details through the event parameter
  4. β€’Understand Propagation: Events bubble up by default; use stopPropagation when needed
  5. β€’Prevent Defaults Wisely: Only preventDefault when you're handling the action yourself

πŸ”— Next Steps

Continue to 10.4 Event Delegation to learn how to efficiently handle events for multiple elements.

README - JavaScript Tutorial | DeepML