Loading...

JavaScript Event Object

The museum wall holds one plaque. The outer box is #wall. Inside it, #plaque holds a link, #seal, the word on it is open, and href is /wing. Under the wall, #slip says blank.
The browser hands the handler one object. Name the parameter event. event.type is the kind of event. A click makes that string click. event.target is the element the click landed on. event.currentTarget is the element this listener sits on. Those two are the same only when the click and the listener share one element.
The seal is a link. preventDefault cancels the jump to /wing. After that call, event.defaultPrevented is true. Skip the call and the flag stays false. The click then travels outward: seal, then plaque, then wall. stopPropagation on the plaque cuts that trip, so a listener on the wall does not run.
The page script clicks the seal once. The line under the plaque reads click / seal / plaque / true / quiet. This page does not assign onclick, does not call removeEventListener, and does not create an element.

The object the browser passes

The previous page put wool and silk on a coat peg. Those functions took no parameter, so they could not read this object. The line there was wool silk / 2 / peg. The doorbell page assigned onclick and read this. This page does not. getElementById only hands you the wall, the plaque, the seal, and the slip.
addEventListener still only stores the function. The object arrives when the click runs the function, not when you add the listener. Read currentTarget inside the function. After the function returns, that property is null.

What one click reports

The slip starts as blank. The link text stays open. Read the rows in order. Each snippet starts from that fresh wall, except the page row, which is the demo at the bottom. The page demo does not call removeEventListener.

📊 What one click reports

Moment What you read Slip text Easy to mix up
listener on the seal, seal.click(), read the type event.type click reading the id as the type
listener on the plaque, click the seal, read target event.target.id seal reading currentTarget
same click, read currentTarget event.currentTarget.id plaque reading target
preventDefault on the seal, then the flag event.defaultPrevented true thinking the link still leaves
no preventDefault event.defaultPrevented false thinking every listener cancels the link
stopPropagation on the plaque, wall also listens marks joined plaque expecting plaque wall
page script, one click the line click / seal / plaque / true / quiet the line ending with wall

A click on the seal is one event object shared by every listener along the trip. type does not change. target does not change. currentTarget changes: it is the element whose listener is running now.
preventDefault talks to the browser’s default action. For this link, that action is following /wing. The call does not take a listener off the list. stopPropagation talks to the trip. It does not cancel the link. Call one and you have not called the other.
join(" ") only puts a space between words already in marks. This page never joins an empty list. The slip starts as the word blank and changes only inside a listener, or in the page script after the click.

The type

The listener sits on the seal. The function names the parameter event and writes event.type into the slip. Then seal.click() runs it.

Read the type

javascript
let seal = document.getElementById("seal");
let slip = document.getElementById("slip");
function readType(event) {
slip.textContent = event.type;
}
seal.addEventListener("click", readType);
seal.click();
console.log(slip.textContent);

The log is click. The type is the kind of event, not the id and not the word open.

The element that was clicked

Fresh wall. The listener sits on the plaque, not on the seal. The click still lands on the seal. event.target is that landing element, so event.target.id is seal.

Read the target

javascript
let plaque = document.getElementById("plaque");
let seal = document.getElementById("seal");
let slip = document.getElementById("slip");
function readTarget(event) {
slip.textContent = event.target.id;
}
plaque.addEventListener("click", readTarget);
seal.click();
console.log(slip.textContent);

The log is seal. The listener’s element is the plaque. target does not report the plaque. It reports the element under the click.

Where the listener sits

Same fresh wall, listener still on the plaque, click still on the seal. The slip writes both ids, target first, then currentTarget.

Read both ids

javascript
let plaque = document.getElementById("plaque");
let seal = document.getElementById("seal");
let slip = document.getElementById("slip");
function readWhere(event) {
slip.textContent = event.target.id + " " + event.currentTarget.id;
}
plaque.addEventListener("click", readWhere);
seal.click();
console.log(slip.textContent);

The log is seal plaque. The first word is the click. The second word is the element that owns this listener. Put that listener on the seal and click the seal: both ids are seal, because the click and the listener share one element. This reading uses the plaque, so the two ids differ. Read currentTarget inside the function. After the function returns, it is null.

Cancel the link

The seal’s href is /wing. The browser’s default for that click is to follow the link. preventDefault cancels that default. It does not remove the listener. Right after the call, event.defaultPrevented is true.

Cancel the link

javascript
let seal = document.getElementById("seal");
let slip = document.getElementById("slip");
function hold(event) {
event.preventDefault();
slip.textContent = String(event.defaultPrevented);
}
seal.addEventListener("click", hold);
seal.click();
console.log(slip.textContent);

The log is true. Leave out preventDefault and the same read is false. The slip would say false, and the link’s default would still be in play. stopPropagation does not set this flag.

The click travels outward

The seal sits in the plaque, and the plaque sits in the wall. A click on the seal reaches a plaque listener, then a wall listener, unless the trip is cut. stopPropagation on the plaque cuts it. The wall function does not run. preventDefault does not cut the trip.

Stop the trip

javascript
let wall = document.getElementById("wall");
let plaque = document.getElementById("plaque");
let seal = document.getElementById("seal");
let slip = document.getElementById("slip");
let marks = [];
function onPlaque(event) {
marks.push("plaque");
event.stopPropagation();
}
function onWall() {
marks.push("wall");
}
plaque.addEventListener("click", onPlaque);
wall.addEventListener("click", onWall);
seal.click();
slip.textContent = marks.join(" ");
console.log(slip.textContent);

The log is plaque. The word wall never joins the marks. Without stopPropagation, the same click would write plaque wall. The page demo below stops the trip and also cancels the link.

One line under the plaque

The script sits at the end of the body, after the wall and the paragraphs exist. The seal listener calls preventDefault. The plaque listener calls stopPropagation, then stores the type, the target id, the currentTarget id, and the flag. The wall listener would set heard to wall, but the trip is already cut, so heard stays quiet. The line is written after seal.click(), when the wall has had its chance.

Page demo — museum plaque

html
<!DOCTYPE html>
<html>
<head>
<title>event-object — page</title>
</head>
<body>
<div id="wall">
<div id="plaque">
<a id="seal" href="/wing">open</a>
</div>
</div>
<p id="slip">blank</p>
<p id="line">…</p>
<script>
let wall = document.getElementById("wall");
let plaque = document.getElementById("plaque");
let seal = document.getElementById("seal");
let slip = document.getElementById("slip");
let kind = "";
let from = "";
let on = "";
let held = "";
let heard = "quiet";
seal.addEventListener("click", function (event) {
event.preventDefault();
});
plaque.addEventListener("click", function (event) {
event.stopPropagation();
kind = event.type;
from = event.target.id;
on = event.currentTarget.id;
held = String(event.defaultPrevented);
});
wall.addEventListener("click", function () {
heard = "wall";
});
seal.click();
slip.textContent = kind + " " + from + " " + on;
document.getElementById("line").textContent =
kind + " / " + from + " / " + on + " / " + held + " / " + heard;
</script>
</body>
</html>

The line reads click / seal / plaque / true / quiet. The type is click. The target id is seal. The currentTarget id is plaque, because that listener sits on the plaque. The flag is true, because the seal listener called preventDefault before the plaque listener read it. The last token is quiet, not wall, because stopPropagation ran on the plaque. The link text open is not in the line. The slip becomes click seal plaque. The next page is delegation. The seal is already in the markup. This page does not add a child after the listener.

Five checks at the plaque

  1. Put the listener on the seal and click. The slip is click.
  2. Put the listener on the plaque, click the seal, and read event.target.id. The slip is seal.
  3. Same listener, write both ids. The slip is seal plaque. A listener on the seal itself would write seal seal.
  4. Call preventDefault, then read event.defaultPrevented. The slip is true. Skip the call and the slip is false.
  5. Call stopPropagation on the plaque while the wall also listens. The marks join to plaque. Read the page line: click / seal / plaque / true / quiet.

Where this plaque tricks you

The link still says open. The slip is not the link text.

  • Expecting the handler argument to be the seal element, rather than the event object
  • Reading event.target when you wanted the element the listener sits on
  • Reading event.currentTarget when you wanted the element under the click
  • Expecting preventDefault to remove the listener, the way removeEventListener did on the peg
  • Expecting stopPropagation to cancel the jump to /wing
  • Expecting the wall listener to run after stopPropagation on the plaque
  • Reading event.currentTarget after the function has returned, and expecting plaque
  • Assigning onclick, or reading this and typeof null; the doorbell page did that
  • Building the link with createElement; an earlier page did that
  • Reading the line as ending with wall, or as wool silk / 2 / peg

What stays with you

  • event.type after a click is click
  • With the listener on the plaque and the click on the seal, event.target.id is seal
  • On that same click, event.currentTarget.id is plaque
  • With the listener on the seal, target and currentTarget are both the seal
  • preventDefault makes event.defaultPrevented true, and skipping it leaves false
  • stopPropagation on the plaque keeps the wall listener from running
  • The page line reads click / seal / plaque / true / quiet

🧠 Test Your Knowledge

Ready to Start

Test Your Knowledge

Challenge yourself with this interactive quiz and see how well you understand the topic

❓
8
Questions
🎯
70%
To Pass
♾️
∞
Time
🔄
∞
Attempts

📝 Instructions

  • Read each question carefully
  • Select the best answer for each question
  • You can retake the quiz as many times as you want
  • Your progress will be shown at the top