#CodeNewbie

#CodingTips

#Frontend

#Fullstack

#JavaScript

#LearnToCode

#Programming

#WebDevelopment

JavaScript events: click, input, submit — a complete addEventListener guide

Events are how JavaScript responds to user actions — clicks, key presses, form submissions, mouse movements, and more. Understanding events and how to listen for them is the core skill that makes web pages interactive. This article covers everything from basic click handlers to event delegation and stopping propagation.


 

What is an event?

An event is a signal that something has happened in the browser — a user clicked a button, typed in a field, scrolled the page, or the document finished loading. JavaScript lets you listen for these signals and run a function in response.

There are three ways to attach events to elements. The modern and recommended way is addEventListener().

// ❌ Old way 1 — inline HTML (avoid)
<button onclick="handleClick()">Click</button>

// ❌ Old way 2 — event property (only one handler)
btn.onclick = function() { ... };

// ✅ Modern way — addEventListener (recommended)
btn.addEventListener("click", function() { ... });

 

addEventListener syntax

element.addEventListener(eventType, handler, options);

// eventType — string: "click", "input", "submit", etc.
// handler — function to run when event fires
// options — optional: { once: true, capture: true }

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

btn.addEventListener("click", function() {
  console.log("Button clicked!");
});

// Arrow function shorthand
btn.addEventListener("click", () => {
  console.log("Button clicked!");
});

// Named function (reusable + removable)
function handleClick() {
  console.log("Button clicked!");
}
btn.addEventListener("click", handleClick);
btn.removeEventListener("click", handleClick);
You can attach multiple listeners to the same element for the same event with addEventListener — something you cannot do with the onclick property. The listeners fire in the order they were added.

 

The event object

When an event fires, the browser automatically passes an event object to your handler function. This object contains useful information about what happened.

btn.addEventListener("click", (event) => {
  console.log(event.type);       →  "click"
  console.log(event.target);     →  the element that was clicked
  console.log(event.clientX);    →  mouse X position
  console.log(event.clientY);    →  mouse Y position
  console.log(event.timeStamp);  →  when it happened (ms)
});

// event.target vs event.currentTarget
// target — the element that was actually clicked
// currentTarget — the element the listener is attached to

 

Common event types

MOUSE EVENTS

"click"      ← single click
"dblclick"   ← double click
"mousedown"  ← mouse button pressed
"mouseup"    ← mouse button released
"mousemove"  ← mouse moves over element
"mouseover"  ← mouse enters element (includes children)
"mouseenter" ← mouse enters element (ignores children)
"mouseleave" ← mouse leaves element
"contextmenu"← right-click

KEYBOARD EVENTS

"keydown"  ← key pressed (fires repeatedly while held)
"keyup"    ← key released
"keypress" ← deprecated, use keydown instead

document.addEventListener("keydown", (e) => {
  console.log(e.key);    →  "Enter", "a", "ArrowUp"
  console.log(e.code);   →  "KeyA", "Enter", "Space"
  console.log(e.ctrlKey); →  true if Ctrl held
  console.log(e.shiftKey); →  true if Shift held
});

FORM EVENTS

"input"   ← fires on every keystroke in an input field
"change"  ← fires when value changes and field loses focus
"submit"  ← fires when a form is submitted
"focus"   ← fires when an input is focused
"blur"    ← fires when an input loses focus

PAGE AND WINDOW EVENTS

"DOMContentLoaded" ← HTML parsed, DOM ready
"load"             ← page fully loaded (images, styles)
"scroll"           ← user scrolls the page
"resize"           ← window is resized

 

Practical examples

HANDLING A FORM SUBMIT

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

form.addEventListener("submit", (e) => {
  e.preventDefault();  ← stop page from reloading
  
  const email = document.querySelector("#email").value;
  const pass  = document.querySelector("#password").value;
  
  console.log("Submitted:", email, pass);
});

LIVE INPUT FEEDBACK

const input = document.querySelector("#search");
const output = document.querySelector("#results");

input.addEventListener("input", (e) => {
  output.textContent = `Searching: ${e.target.value}`;
});

KEYBOARD SHORTCUT

document.addEventListener("keydown", (e) => {
  if (e.ctrlKey && e.key === "s") {
    e.preventDefault();
    console.log("Saving...");
  }
});

 

Event bubbling and capturing

When an event fires on an element, it does not stay there. It travels up through parent elements all the way to the document. This is called event bubbling.

/* HTML: <div id="outer"><button id="inner">Click</button></div> */

document.querySelector("#inner").addEventListener("click", () => {
  console.log("inner clicked");
});

document.querySelector("#outer").addEventListener("click", () => {
  console.log("outer clicked");
});

// Click the button → both fire:
→  inner clicked
→  outer clicked  ← bubbles up to parent

STOPPING BUBBLING

document.querySelector("#inner").addEventListener("click", (e) => {
  e.stopPropagation();  ← stops the event from bubbling up
  console.log("inner only");
});

 

Event delegation

Instead of attaching a listener to every child element, you can attach one listener to the parent and use event.target to figure out which child was clicked. This is called event delegation — it is more efficient and works even for elements added to the DOM later.

/* HTML: <ul id="list"><li>Item 1</li><li>Item 2</li></ul> */

// ❌ Bad — listener on every li
document.querySelectorAll("li").forEach(li => {
  li.addEventListener("click", () => console.log(li.textContent));
});

// ✅ Good — one listener on the parent
document.querySelector("#list").addEventListener("click", (e) => {
  if (e.target.tagName === "LI") {
    console.log(e.target.textContent);
  }
});
Event delegation is the recommended pattern for lists, tables, and any dynamic content where items are added or removed. One listener beats dozens of listeners every time.

 

Key takeaways

Always use addEventListener() — it supports multiple listeners and is removable. The event object passed to your handler contains everything you need: type, target, position, and key info. Use e.preventDefault() to stop default browser behaviour (form reload, link navigation). Use e.stopPropagation() to stop an event from bubbling to parent elements. Event bubbling makes event delegation possible — attach one listener to a parent instead of many listeners to each child.