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.
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.
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.
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.
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.
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.
<!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
- Put the listener on the seal and click. The slip is click.
- Put the listener on the plaque, click the seal, and read
event.target.id. The slip is seal. - Same listener, write both ids. The slip is seal plaque. A listener on the seal itself would write seal seal.
- Call
preventDefault, then readevent.defaultPrevented. The slip is true. Skip the call and the slip is false. - Call
stopPropagationon 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.targetwhen you wanted the element the listener sits on - Reading
event.currentTargetwhen you wanted the element under the click - Expecting
preventDefaultto remove the listener, the wayremoveEventListenerdid on the peg - Expecting
stopPropagationto cancel the jump to/wing - Expecting the wall listener to run after
stopPropagationon the plaque - Reading
event.currentTargetafter the function has returned, and expecting plaque - Assigning
onclick, or readingthisandtypeof 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.typeafter a click is click- With the listener on the plaque and the click on the seal,
event.target.idis seal - On that same click,
event.currentTarget.idis plaque - With the listener on the seal, target and currentTarget are both the seal
preventDefaultmakesevent.defaultPreventedtrue, and skipping it leaves falsestopPropagationon the plaque keeps the wall listener from running- The page line reads click / seal / plaque / true / quiet
🧠 Test Your Knowledge
Test Your Knowledge
Challenge yourself with this interactive quiz and see how well you understand the topic
📝 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