JavaScript course menu
JavaScript Events: addEventListener, the Event Object and Common Events
Learn JavaScript events: listening with addEventListener, the event object and event.target, common mouse, keyboard, input and page events, preventDefault, removing listeners, once and passive options, and why to avoid inline onclick attributes.
On this page
An event is something that happens in the page: a click, a key press, typing in a field, the page finishing loading, the window being resized. JavaScript can listen for events and run a function (an event handler) when they happen.
addEventListener#
element.addEventListener("click", handler);<button id="btn">Click me</button>
<p id="out">Not clicked yet.</p>let clicks = 0;
const out = document.querySelector("#out");
function handleClick() {
clicks++;
out.textContent = `Clicked ${clicks} time${clicks === 1 ? "" : "s"}`;
}
document.querySelector("#btn").addEventListener("click", handleClick);- The first argument is the event type, as a string:
"click", not"onclick". - The second is the function to call. Pass the function itself (
handleClick), not a call (handleClick()), which would run it immediately. - You can add several listeners to the same element and event; they all run.
The event object#
Each handler receives an event object with details about what happened:
<div id="pad" style="height: 90px; background: #eef3ff; border: 1px dashed #2f5fe0; display: grid; place-items: center">
Move or click inside this box
</div>
<p id="out"></p>const out = document.querySelector("#out");
const pad = document.querySelector("#pad");
pad.addEventListener("mousemove", (event) => {
out.textContent = `x: ${event.offsetX}, y: ${event.offsetY}`;
});
pad.addEventListener("click", (event) => {
out.textContent = `Clicked ${event.target.id} with ${event.shiftKey ? "Shift held" : "no Shift"}`;
});Common events#
Pointer events cover mouse, touch and pen in one model, so they are a good choice for drawing and dragging.
Keyboard events#
<input id="search" placeholder="Type, then press Enter or Escape" size="36">
<p id="out"></p>const input = document.querySelector("#search");
const out = document.querySelector("#out");
input.addEventListener("keydown", (event) => {
if (event.key === "Enter") {
out.textContent = `Searching for "${input.value}"`;
} else if (event.key === "Escape") {
input.value = "";
out.textContent = "Cleared";
}
});Use event.key (such as "Enter", "Escape", "ArrowUp", "a"). The old keyCode property is deprecated.
Preventing the default action#
Some events have a built-in browser action: a link navigates, a form submits, a right-click opens a menu. event.preventDefault() cancels it:
<a href="https://example.com" id="link">A link that will not navigate</a>
<p id="out"></p>document.querySelector("#link").addEventListener("click", (event) => {
event.preventDefault();
document.querySelector("#out").textContent = "Default navigation was prevented.";
});The most common use is handling form submission in JavaScript (Handling Forms).
Removing listeners and options#
To remove a listener, pass the same function reference to removeEventListener:
function onScroll() { /* ... */ }
window.addEventListener("scroll", onScroll);
window.removeEventListener("scroll", onScroll);An anonymous arrow function cannot be removed this way, because you have no reference to it. The third argument takes options:
Avoid inline handlers#
You may see handlers written in HTML attributes:
<button onclick="handleClick()">Click</button>This mixes behaviour into markup, allows only one handler, needs global functions, and is blocked by strict Content Security Policies. Use addEventListener in your JavaScript instead.
Accessibility#
- Use real
<button>and<a href>elements for clickable things: they get keyboard support automatically. Aclicklistener on a<button>also fires when it is activated withEnterorSpace. - Do not rely on mouse-only events such as
mouseenterfor essential features.
Practice#
Practice exercise
Make a character counter: a <textarea> with a maxlength of 100 and a paragraph that shows "N / 100 characters" as the user types, turning red when fewer than 10 characters remain.
Show solution
<textarea id="msg" maxlength="100" rows="3" cols="40"></textarea>
<p id="count">0 / 100 characters</p>const msg = document.querySelector("#msg");
const count = document.querySelector("#count");
msg.addEventListener("input", () => {
const used = msg.value.length;
count.textContent = `${used} / 100 characters`;
count.style.color = 100 - used < 10 ? "crimson" : "";
});The input event fires on every change, including pasting and deleting, which makes it better than keydown for this.
Key takeaway#
Finished this lesson?