In JavaScript, an event is simply an indicator that something has happened. This allows our code to respond dynamically to various situations. For example:
- A user presses a key.
- A timer finishes.
- A signal is received from an API.
Events are a simple mechanism for asynchronous programming, as they allow us to manage tasks in a non-blocking way.
Event handling is slightly different depending on whether it’s done in a browser or in a runtime like Node.js.
The concepts are the same, but the syntax is somewhat different. We’ll see this throughout the article.
How events work
When starting with events, one of the tricky things is understanding the concepts and terms (without mixing them up).
The event in JavaScript is an occurrence that happens in the browser. For example, it can be caused by the user or by the system.
To respond to the event, we need to associate a function called event handlers, which will execute when the event occurs.
Finally, the event also includes an object that contains information about the event.
In summary:
- Event: An occurrence that happens
- Event handler: A function that executes when the event occurs
- Event object: An object containing information about the event
Event handler functions
The event handler function is simply a function we define that will execute when the event occurs.
To do this, we first need to associate a function with an event emitter.
To associate the function with the event we use the methods:
- In the browser:
addEventListener - In Node.js:
on
// Bind a handler with `addEventListener`
myEmitter.addEventListener("myEvent", (event) => {
console.log("Handling the event:", event);
});
How to trigger an event in JavaScript
Triggering an event, also known as emitting an event, involves creating an instance of the event and triggering it on a specific object.
JavaScript provides several ways to do this. The most common method for triggering events in JavaScript is:
- In the browser:
dispatchEvent. - In Node.js:
emit.
// Create a standard event
let event = new Event("myEvent");
// Fire the event
document.dispatchEvent(event);
In this example:
- We create an event called
myEvent. - We use
dispatchEventto trigger it, thus activating the associated handler.
Basic example
Let’s see how to combine event emission with the handler function, with some complete examples.
In the browser
In the browser, events are fundamental for interacting with the user interface. For example, you can listen for events like click, submit, or keydown on HTML elements and react to them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Events in the Browser</title>
</head>
<body>
<button id="myButton">Click here</button>
<script>
// Select the button
let button = document.getElementById("myButton");
// Add a handler for the 'click' event
button.addEventListener("click", () => {
console.log("The button was clicked");
});
</script>
</body>
</html>
In this example:
- The
clickevent is used to detect when the user clicks a button.
Using events in Node.js
Node.js includes the events module, which provides the EventEmitter class, allowing you to register handlers and emit events.
import { EventEmitter } from "events";
// Class that simulates being a server
class Server extends EventEmitter {
start() {
console.log("Server started");
this.emit("serverStarted"); // emits an event on start
}
}
// Create an instance of the server
const server = new Server();
// Register handler for the event
server.on("serverStarted", () => {
console.log("The server is ready to receive requests");
});
// Simulate server execution
server.start();
Here:
- We create an event emitter with
EventEmitter. - We register a handler for the
myEventevent usingon. - We use the
emitmethod to trigger the event and pass a message as an argument.
Defining custom events
In addition to handling predefined events, we can create custom events. This is useful in complex projects because we can provide more information than with generic events.
To create our own events, we can use the Event or CustomEvent classes.
Event
Event is a very simple class that lets us add an (optional) message to identify the event.
// Create a custom event
let customEvent = new Event("myEvent");
// Fire the event
document.dispatchEvent(customEvent);
CustomEvent
CustomEvent extends the capabilities of the standard event, allowing you to pass additional data at the moment of emitting the event.
// Create a custom event with additional data
let customEvent = new CustomEvent("myCustomEvent", {
detail: { message: "Hello from a custom event" },
});
// Assign a handler to receive the data
document.addEventListener("myCustomEvent", (e) => {
console.log(e.detail.message); // Access the custom data
});
// Fire the event
document.dispatchEvent(customEvent);
In this case, we use the detail property to include additional information that handlers can process.
Integrating events with promises
Sometimes, you may want to integrate event handling with Promises. This is useful for synchronizing asynchronous tasks.
function waitForEvent(event) {
return new Promise((resolve) => {
document.addEventListener(event, resolve, { once: true });
});
}
async function main() {
console.log("Waiting for event...");
await waitForEvent("myEvent");
console.log("Event received.");
}
// Execute and simulate the event
main();
document.dispatchEvent(new Event("myEvent"));
Here, the waitForEvent function converts an event into a Promise, allowing you to wait for its resolution within an asynchronous function.
