Loading...

JavaScript Events

The apartment door has one bell. The button is #bell, and the word on it is press. Under it, #chime says silent. The markup has no onclick attribute, so bell.onclick starts as null. typeof null is "object" in JavaScript, so typeof bell.onclick is "object" too. It is not "null" and it is not "undefined". The comparison bell.onclick === null is true.
Putting a function in onclick does not ring the bell. The chime stays silent until bell.click() runs the function that sits in the slot. The property holds one function. Assign a second function and the first one is gone. One click does not run both. addEventListener is the next page; that page can stack listeners. This page does not call it.
bell.onclick = null empties the slot. A click after that leaves the chime text alone. Inside the handler, this is the button, so this.id is bell. The word on the button stays press. The page script clicks once. The line under the bell reads dong / 1 / bell. This page does not create an element and does not set a CSS property.

One slot on the button

The previous page built li nodes with createElement, then placed them with append, prepend, and insertBefore. This page does not build a node and does not read children. The page before that wrote style and classList on a paint chip. This page does not assign style. getElementById only hands you the button and the chime. The new idea is the onclick property: one function, or null.

What the slot holds

The button starts with press on it and silent under it. Read the rows in order. Each snippet starts from that fresh button, except the page row, which is the demo at the bottom. The page demo does not assign null.

📊 What the slot holds

Moment What onclick holds Chime text Easy to mix up
before any assignment null; typeof is "object" silent reading typeof as "null"
after the ding function, before click a function silent the assignment ringing the bell
after click with ding that function ding the button text becoming ding
dong replaces ding, then one click the dong function, not ding dong both functions running
onclick = null, then click, fresh button null; typeof is "object" silent a cleared slot still ringing
page script, one click a function; this.id is bell dong the line ending with silent

onclick is a property on the element. With no handler, the value is null, and typeof null is still "object". Use === null when you want to know the slot is empty. Assigning the property stores the function. It does not call it. bell.click() fires a click and runs whatever function is in the slot right then. The call does not change the button’s own text. A second assignment overwrites the property. The first function object still exists in memory if you kept a name for it, and the property no longer points at it. onclick = null removes the handler. An HTML onclick attribute would fill the same slot; this button has no such attribute. An arrow function in this slot would not set this to the button. This page uses a plain function.

The slot starts empty

The file opens with the button and the paragraph. Nothing has been assigned. These four logs ask the property, its typeof, the chime, and the word on the button.

Quiet bell

javascript
let bell = document.getElementById("bell");
let chime = document.getElementById("chime");
console.log(bell.onclick);
console.log(typeof bell.onclick);
console.log(chime.textContent);
console.log(bell.textContent);

The logs are null, object, silent, and press. The property is empty. typeof does not print null. The button and the chime still show the words from the markup.

The function waits

onclick = function ... stores the function. The body does not run on that line. The chime is still silent, and the property is no longer null.

Assign, do not ring

javascript
let bell = document.getElementById("bell");
let chime = document.getElementById("chime");
bell.onclick = function () {
chime.textContent = "ding";
};
console.log(typeof bell.onclick);
console.log(chime.textContent);
console.log(bell.onclick === null);

The logs are function, silent, and false. You can see a function in the slot. The paragraph has not changed, because nothing called the function.

click runs the one in the slot

bell.click() runs the current handler. The chime becomes ding. The button text stays press. The slot still holds a function after the click.

Ring once

javascript
let bell = document.getElementById("bell");
let chime = document.getElementById("chime");
bell.onclick = function () {
chime.textContent = "ding";
};
bell.click();
console.log(chime.textContent);
console.log(bell.textContent);
console.log(typeof bell.onclick);

The logs are ding, press, and function. One click, one change, and it is the paragraph that changes. The word press is still the button.

The second function replaces the first

This snippet starts from the fresh button again. ding is stored, then dong is stored over it, and only then comes one click. There is no click between the two assignments, so the chime never becomes ding in this run. After the click it is dong. bell.onclick === ding is false. bell.onclick === dong is true.

Second function wins

javascript
let bell = document.getElementById("bell");
let chime = document.getElementById("chime");
function ding() {
chime.textContent = "ding";
}
function dong() {
chime.textContent = "dong";
}
bell.onclick = ding;
bell.onclick = dong;
bell.click();
console.log(bell.onclick === ding);
console.log(bell.onclick === dong);
console.log(chime.textContent);

The logs are false, true, and dong. The name ding still refers to a function. The property does not. One click ran dong only.

null empties the slot

Run this on the fresh button. A function is assigned and then cleared before any click. bell.click() after null does not write dong. The chime stays silent. typeof is object again, because the value is null.

Clear the slot

javascript
let bell = document.getElementById("bell");
let chime = document.getElementById("chime");
bell.onclick = function () {
chime.textContent = "dong";
};
bell.onclick = null;
bell.click();
console.log(bell.onclick);
console.log(typeof bell.onclick);
console.log(chime.textContent);

The logs are null, object, and silent. The function that would have written dong is not in the slot at click time. The page demo below does not clear the slot.

One line under the bell

The script sits at the end of the body, after the button and the paragraph exist. It stores one function, then calls click once. Inside the function, taps goes from 0 to 1, the chime becomes dong, and this.id is written to bell.dataset.who. The line joins the chime, the tap count, and that id. It does not write the button text.

Page demo — doorbell

html
<!DOCTYPE html>
<html>
<head>
<title>events — page</title>
</head>
<body>
<button id="bell" type="button">press</button>
<p id="chime">silent</p>
<p id="line">…</p>
<script>
let bell = document.getElementById("bell");
let chime = document.getElementById("chime");
let taps = 0;
bell.onclick = function () {
taps = taps + 1;
chime.textContent = "dong";
bell.dataset.who = this.id;
};
bell.click();
document.getElementById("line").textContent =
chime.textContent + " / " + taps + " / " + bell.dataset.who;
</script>
</body>
</html>

The line reads dong / 1 / bell. The chime is dong, not silent. The count is 1, because the script clicks once. The last token is the button id, from this inside the handler, not the word press. The button still says press. The next page is event listeners. It does not use this single onclick slot as its main tool.

Five rings to check

  1. Read onclick, typeof bell.onclick, the chime, and the button text. The values are null, object, silent, and press.
  2. Assign the ding function and do not click. typeof is function, the chime is silent, and onclick === null is false.
  3. Call bell.click() with that ding function. The chime is ding, the button is press, and typeof is function.
  4. Assign ding, then dong, then click once. onclick === ding is false, onclick === dong is true, and the chime is dong.
  5. On a fresh button, assign a function, set onclick to null, then click. The values are null, object, and silent. Read the page line: dong / 1 / bell.

Where this bell tricks you

The button still says press. The slot held the wrong function, or it held nothing.

  • Reading typeof bell.onclick as "null" while the value is null
  • Expecting the assignment itself to change the chime to ding
  • Expecting both ding and dong to run on one click after the second assignment
  • Expecting the button text to become ding
  • Expecting click to change the chime after onclick = null
  • Using an arrow function and expecting this.id to be bell
  • Reading event.target here; these handlers take no argument, and the event object is a later page
  • Calling addEventListener here; the next page stacks listeners
  • Building the button with createElement; the previous page did that
  • Reading the line as silent / 0 / press

What stays with you

  • With no handler, bell.onclick is null and typeof bell.onclick is object
  • Assigning a function leaves the chime silent until click
  • bell.click() with the ding function sets the chime to ding and leaves the button as press
  • A second assignment replaces the first, so one click runs dong only
  • onclick = null then click on a fresh button leaves the chime silent
  • The page line reads dong / 1 / bell, and this.id inside the handler is bell

🧠 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