Class 12: JavaScript Events & Asynchronous Programming
In the previous class, we learned how to manipulate the DOM to dynamically change web page content and styles. Now, we'll dive into how JavaScript can react to user actions and manage tasks that don't happen instantly. This class introduces JavaScript Events for handling user interactions and the basics of Asynchronous Programming.

Handling User Interactions with Events
Events are actions or occurrences that happen in the system you are programming, which the system tells you about so your code can react. When a user clicks a button, submits a form, or types into an input field, these are all events.
addEventListener()
The addEventListener()
method is the most common
and recommended way to register an event handler. It attaches an
event handler to the specified element without overwriting
existing event handlers.
<!-- HTML -->
<button id="myButton">Click Me!</button>
<p id="message">No click yet.</p>
<script>
const button = document.getElementById("myButton");
const message = document.getElementById("message");
// Define the function to be executed when the event occurs
function handleClick() {
message.textContent = "Button was clicked!";
console.log("Button clicked!");
}
// Attach the click event listener to the button
button.addEventListener("click", handleClick);
// You can also use an anonymous function directly
// button.addEventListener("mouseover", () => {
// message.textContent = "Mouse over button!";
// });
</script>
- The first argument is the type of event (e.g., "click", "mouseover").
- The second argument is the function to be called when the event occurs (the event handler or listener).
Common DOM Events
Here are some frequently used DOM events:
click
: When an element is clicked.-
mouseover
: When the mouse pointer enters an element. -
mouseout
: When the mouse pointer leaves an element. keydown
: When a key is pressed down.keyup
: When a key is released.submit
: When a form is submitted.-
change
: When the value of an input, select, or textarea element changes. -
load
: When a resource (like an image or the entire page) has finished loading.
<!-- HTML -->
<input type="text" id="myInput" placeholder="Type something...">
<form id="myForm">
<input type="text" placeholder="Name">
<button type="submit">Submit</button>
</form>
<p id="keyOutput"></p>
<script>
const myInput = document.getElementById("myInput");
const myForm = document.getElementById("myForm");
const keyOutput = document.getElementById("keyOutput");
myInput.addEventListener("change", (event) => {
console.log("Input value changed to: ", event.target.value);
});
myForm.addEventListener("submit", (event) => {
event.preventDefault(); // Prevents the default form submission (page reload)
console.log("Form submitted!");
alert("Form Submitted! (Check console)");
});
document.addEventListener("keydown", (event) => {
keyOutput.textContent = `Key pressed: ${event.key}`;
if (event.key === "Escape") {
alert("Escape key pressed!");
}
});
</script>
The Event Object
When an event occurs, an Event
object is
automatically passed as the first argument to the event listener
function. This object contains useful information about the
event, such as the element that triggered it
(event.target
), mouse coordinates, key pressed,
etc.
<!-- HTML -->
<div id="clickableDiv" style="width: 100px; height: 100px; background-color: lightblue;">
Click Me!
</div>
<p id="coords"></p>
<script>
const clickableDiv = document.getElementById("clickableDiv");
const coordsParagraph = document.getElementById("coords");
clickableDiv.addEventListener("click", (event) => {
console.log("Event type:", event.type); // "click"
console.log("Target element:", event.target); // The div element
console.log("Client X:", event.clientX); // X coordinate relative to viewport
console.log("Client Y:", event.clientY); // Y coordinate relative to viewport
coordsParagraph.textContent = `Clicked at (${event.clientX}, ${event.clientY})`;
});
</script>
Event Propagation (Bubbling, Capturing)
When an event occurs on an element, it doesn't just happen on that element. It propagates through the DOM tree.
-
Capturing Phase: The event first travels
from the
window
down to the target element. - Target Phase: The event reaches the actual target element.
-
Bubbling Phase: The event then bubbles up
from the target element back to the
window
.
Most events bubble by default.
addEventListener()
defaults to the bubbling phase.
<!-- HTML -->
<div id="outer" style="padding: 20px; background-color: #f0f0f0;">
Outer Div
<div id="inner" style="padding: 20px; background-color: lightcoral;">
Inner Div
</div>
</div>
<script>
const outer = document.getElementById("outer");
const inner = document.getElementById("inner");
// Bubbling Phase (default)
outer.addEventListener("click", () => {
console.log("Outer Div (Bubbling)");
});
inner.addEventListener("click", () => {
console.log("Inner Div (Bubbling)");
});
// Capturing Phase (third argument true)
outer.addEventListener("click", () => {
console.log("Outer Div (Capturing)");
}, true);
inner.addEventListener("click", () => {
console.log("Inner Div (Capturing)");
}, true);
</script>
event.stopPropagation()
can be used inside an event
handler to stop the event from propagating further.
Introduction to Asynchronous Programming (Part 1)
JavaScript is primarily single-threaded, meaning it executes one task at a time, in order. However, many operations, like fetching data from a server, reading a file, or waiting for a user click, take time and would "block" the main thread, making the web page unresponsive. Asynchronous JavaScript allows these long-running tasks to run in the background without blocking the main thread.
Think of it like ordering food:
- Synchronous: You order, wait by the counter, and cannot do anything else until your food is ready.
- Asynchronous: You order, get a buzzer (or leave your number), and go sit down or do other things. The buzzer notifies you when your food is ready, and then you pick it up.
setTimeout()
Executes a function or a block of code after a specified delay (in milliseconds). It's a one-time execution.
console.log("Start of script");
setTimeout(() => {
console.log("This message appears after 2 seconds.");
}, 2000); // 2000 milliseconds = 2 seconds
console.log("End of script (will appear before the timeout message).");
/* Expected Output:
Start of script
End of script (will appear before the timeout message).
(after 2 seconds)
This message appears after 2 seconds.
*/
-
The
setTimeout
function is non-blocking. JavaScript registers the timer and immediately moves to the next line of code. - The callback function (the first argument) is added to a "callback queue" and executed only after the main thread is free and the timer expires.
setInterval()
Repeatedly executes a function or a block of code with a fixed time delay between each call. It keeps running until stopped.
let count = 0;
const intervalId = setInterval(() => {
count++;
console.log(`Interval tick: ${count}`);
if (count === 3) {
clearInterval(intervalId); // Stop the interval after 3 ticks
console.log("Interval stopped.");
}
}, 1000); // Executes every 1 second
console.log("Counting will start soon...");
/* Expected Output:
Counting will start soon...
(after 1 second)
Interval tick: 1
(after another 1 second)
Interval tick: 2
(after another 1 second)
Interval tick: 3
Interval stopped.
*/
setInterval
also runs asynchronously.-
clearInterval(id)
is used to stop asetInterval
loop, whereid
is the value returned bysetInterval
.
Understanding events allows you to make your web pages interactive, and grasping asynchronous concepts is vital for handling operations that take time, ensuring your applications remain responsive.