To respond to an event, you attach an event listener to an element. An event listener is a function that "listens" for a specific event and runs whenever it happens.
Here's a complete example. First, the HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Events Practice</title>
</head>
<body>
<h1 id="message">Nobody has clicked yet.</h1>
<button id="click-me">Click me!</button>
<script src="script.js"></script>
</body>
</html>
And the JavaScript:
const button = document.querySelector("#click-me");
const message = document.querySelector("#message");
button.addEventListener("click", () => {
message.textContent = "You clicked the button! 🎉";
});
Open the page and click the button. The heading changes! Your page just reacted to the user. 🎉
Let's look at addEventListener closely:
element.addEventListener("eventName", callbackFunction);
elementis the element to listen on (here, the button)."click"is the type of event to listen for, as a string.- The callback is the function to run when the event happens. (Callbacks again! Told you they'd be everywhere.)
The callback doesn't run when you call addEventListener. It runs later, every single time the event happens. Click the button five times, and the function runs five times.
Using a named function
The callback can be an arrow function (like above), or a normal named function. Named functions are handy when the code is longer, or when you want to use the same function for several elements:
function celebrate() {
message.textContent = "Woohoo! 🥳";
}
button.addEventListener("click", celebrate);
Notice it's celebrate, not celebrate(). We're handing over the recipe card for the browser to use later, not cooking the meal right now. (Remember this from Grade 6? It's the same idea.)
button.addEventListener("click", celebrate());
This calls celebrate immediately, when the page loads, and then passes its return value (undefined) to addEventListener. The message changes straight away without any click, and clicking does nothing at all. Drop the parentheses!
A click counter
Let's combine events with a variable to count clicks:
const button = document.querySelector("#click-me");
const message = document.querySelector("#message");
let clicks = 0;
button.addEventListener("click", () => {
clicks++;
message.textContent = `You've clicked ${clicks} ${clicks === 1 ? "time" : "times"}.`;
if (clicks === 10) {
message.textContent += " 🏆 Achievement unlocked: Clicky Fingers!";
}
});
Every click adds one to clicks, and the callback remembers the variable between clicks because it's a closure (Grade 9!).
Removing a listener
If you want to stop listening, use removeEventListener with the same named function:
function sayHi() {
console.log("Hi!");
}
button.addEventListener("click", sayHi);
// later...
button.removeEventListener("click", sayHi);
(This only works with named functions. An arrow function written directly inside addEventListener can't be removed this way, because you have no name to refer to it by.)