πŸŽ“ Velnov

🟨 JavaScript · Topic 17 of 20

Events β€” JavaScript Questions with Answers

30 practice questions on Events, each with the correct answer and a clear explanation of why it is right. Read through them as revision notes, or take this topic as an interactive quiz to test yourself.

1 easy Β· 17 medium Β· 12 hard Β· Part of JavaScript: The language of the web - basics to advanced, 20 topics.

Key concepts in this topic

addEventListenerEventsCallbacksCommon mistakesEvent objecttargetcurrentTargetDelegationpreventDefaultFormsstopPropagationBubblingPropagationCapturingPerformanceDynamic contentremoveEventListenerCleanupListener optionsinputchangeKeyboard eventse.keyFormData

Jump to: Easy Β· Medium Β· Hard

Easy questions (1)

Q1. easy

What is the modern way to react to a click?

btn.addEventListener("click", () => console.log("clicked"));
  1. A btn.addEventListener("click", handler)
  2. B btn.onClick = handler
  3. C btn.click(handler)
  4. D btn.on("click", handler)

Answer: A β€” btn.addEventListener("click", handler)

addEventListener allows MULTIPLE handlers for the same event and supports options like once and capture. The onclick property allows only one handler.

addEventListenerEvents

Medium questions (17)

Q3. medium

What is the event object passed to a handler?

btn.addEventListener("click", (e) => {
  console.log(e.type, e.target, e.clientX);
});
  1. A An object describing what happened - target, type, coordinates, key pressed, etc.
  2. B The element only
  3. C A string
  4. D Nothing is passed

Answer: A β€” An object describing what happened - target, type, coordinates, key pressed, etc.

Every handler receives the event as its first argument (conventionally e or event), carrying details and control methods like preventDefault.

Event object

Q5. medium

What does e.preventDefault() do?

form.addEventListener("submit", (e) => {
  e.preventDefault();   // stop page reload
  sendData();
});
  1. A Stops the browser's default action - e.g. a form submitting or a link navigating
  2. B Stops the event bubbling
  3. C Removes the listener
  4. D Prevents all events

Answer: A β€” Stops the browser's default action - e.g. a form submitting or a link navigating

Essential for handling forms with JavaScript, since without it the page reloads and your code appears to do nothing.

preventDefaultForms

Q6. medium

What does e.stopPropagation() do?

  1. A Prevents the event from continuing to bubble up to ancestor elements
  2. B Stops the default action
  3. C Deletes the event
  4. D Cancels all listeners on the page

Answer: A β€” Prevents the event from continuing to bubble up to ancestor elements

Useful when an inner element's click should not also trigger a parent's handler (e.g. clicking inside a modal should not close it). Use sparingly - it can make behaviour hard to trace.

stopPropagationBubbling

Q10. medium

Why does event delegation work for elements added dynamically?

  1. A The listener is on the parent, which already exists - new children bubble to it automatically
  2. B The browser re-scans listeners
  3. C It does not work for new elements
  4. D JavaScript adds listeners automatically

Answer: A β€” The listener is on the parent, which already exists - new children bubble to it automatically

Directly attached listeners only cover elements present at the time. Delegation solves the common bug where newly created buttons stop responding.

DelegationDynamic content

Q11. medium

How do you REMOVE an event listener?

function onClick() { }
btn.addEventListener("click", onClick);
btn.removeEventListener("click", onClick);   // works
  1. A removeEventListener with the SAME function reference used to add it
  2. B removeEventListener("click")
  3. C el.listeners = []
  4. D delete el.onclick

Answer: A β€” removeEventListener with the SAME function reference used to add it

An anonymous inline arrow cannot be removed because you have no reference to it. Store the function in a variable if you plan to remove it.

removeEventListenerCleanup

Q12. medium

What does the { once: true } option do?

btn.addEventListener("click", init, { once: true });
  1. A The listener fires at most once, then removes itself automatically
  2. B It fires once per second
  3. C It only works on one element
  4. D Nothing

Answer: A β€” The listener fires at most once, then removes itself automatically

Ideal for one-time actions like an intro animation or a single-submit guard - no manual cleanup needed.

Listener options

Q13. medium

Which event fires as the user TYPES in an input?

search.addEventListener("input", (e) => filter(e.target.value));
  1. A input - it fires on every change, including paste
  2. B change - only when leaving the field
  3. C keypress only
  4. D submit

Answer: A β€” input - it fires on every change, including paste

Use input for live search or character counters. change fires only after the value is committed (blur or selection), which is better for selects and checkboxes.

inputchange

Q14. medium

How do you detect which key was pressed?

input.addEventListener("keydown", (e) => {
  if (e.key === "Enter") submit();
});
  1. A e.key - a readable string like "Enter", "a", "ArrowUp"
  2. B e.keyCode only
  3. C e.char
  4. D e.button

Answer: A β€” e.key - a readable string like "Enter", "a", "ArrowUp"

e.key is the modern, readable property. e.keyCode is deprecated. Use e.code when you need the physical key regardless of layout.

Keyboard eventse.key

Q15. medium

What is the difference between keydown and keyup?

  1. A keydown fires when the key goes DOWN (and repeats if held); keyup fires on release
  2. B They are identical
  3. C keyup fires first
  4. D keydown only works for letters

Answer: A β€” keydown fires when the key goes DOWN (and repeats if held); keyup fires on release

Use keydown for shortcuts and to preventDefault before the character appears; use keyup when you need the final state after the key is released.

Keyboard events

Q17. medium

What is the difference between mouseover and mouseenter?

  1. A mouseover BUBBLES and re-fires when moving over children; mouseenter fires once for the element itself
  2. B They are identical
  3. C mouseenter bubbles
  4. D mouseover works only on links

Answer: A β€” mouseover BUBBLES and re-fires when moving over children; mouseenter fires once for the element itself

mouseenter/mouseleave are usually what you want for hover effects, because mouseover fires repeatedly as the pointer crosses child elements.

Mouse events

Q19. medium

Which event should you use to run code after the page's HTML is ready?

  1. A DOMContentLoaded
  2. B click
  3. C resize
  4. D beforeunload

Answer: A β€” DOMContentLoaded

DOMContentLoaded fires as soon as the DOM is parsed. Alternatively, adding defer to your script tag achieves the same effect without a listener.

DOMContentLoadedPage lifecycle

Q21. medium

What does the { passive: true } listener option indicate?

window.addEventListener("touchstart", fn, { passive: true });
  1. A That the handler will NOT call preventDefault, letting the browser scroll without waiting
  2. B That the listener runs once
  3. C That the event is ignored
  4. D That it captures

Answer: A β€” That the handler will NOT call preventDefault, letting the browser scroll without waiting

Passive touch/wheel listeners improve scrolling smoothness because the browser need not block to see whether you cancel the default.

PerformanceTouch events

Q23. medium

What is this inside a REGULAR function event handler?

  1. A The element the listener is attached to (same as e.currentTarget)
  2. B window
  3. C The event object
  4. D undefined

Answer: A β€” The element the listener is attached to (same as e.currentTarget)

The DOM binds this to the current element - but an ARROW handler inherits this from the outer scope instead, so use e.currentTarget there.

thisEvents

Q24. medium

Can one element have TWO listeners for the same event?

  1. A Yes with addEventListener - they run in the order added
  2. B No, only one
  3. C Only with capture
  4. D Only on different elements

Answer: A β€” Yes with addEventListener - they run in the order added

This is a key advantage over the onclick property, which each new assignment overwrites.

addEventListenerMultiple handlers

Q26. medium

Which event fires when a form is submitted?

  1. A submit (on the FORM element)
  2. B click on the button only
  3. C send
  4. D post

Answer: A β€” submit (on the FORM element)

Listen on the form, not the button - that way Enter-key submission is also captured. Then call e.preventDefault() to handle it in JavaScript.

Formssubmit

Q28. medium

What does the change event on a checkbox give you?

cb.addEventListener("change", e => console.log(e.target.checked));
  1. A It fires when checked state changes - read e.target.checked (a boolean)
  2. B It gives the text value
  3. C It fires on hover
  4. D It does not work on checkboxes

Answer: A β€” It fires when checked state changes - read e.target.checked (a boolean)

For checkboxes and radios use .checked, not .value (which is the static value attribute).

FormsCheckboxes

Q30. medium

Which is better for a list of 100 buttons: 100 listeners or 1 delegated listener?

  1. A One delegated listener on the parent - less memory and it covers future items
  2. B 100 individual listeners
  3. C They are identical
  4. D Neither works

Answer: A β€” One delegated listener on the parent - less memory and it covers future items

Delegation is the standard solution for lists, tables and any dynamically generated content.

DelegationPerformance

Hard questions (12)

Q2. hard

What is wrong here? btn.addEventListener("click", handleClick());

btn.addEventListener("click", handleClick);          // correct
btn.addEventListener("click", () => handleClick(5));  // with args
  1. A The parentheses CALL handleClick immediately and register its return value instead of the function
  2. B Nothing is wrong
  3. C The event name is wrong
  4. D It needs three arguments

Answer: A β€” The parentheses CALL handleClick immediately and register its return value instead of the function

Pass the function itself (no parentheses). If you must pass arguments, wrap it: () => handleClick(id).

  • A top beginner mistake with event listeners.

CallbacksCommon mistakes

Q4. hard

What is the difference between e.target and e.currentTarget?

  1. A target is the element that ACTUALLY triggered the event; currentTarget is the element the listener is attached to
  2. B They are always the same
  3. C currentTarget is the parent
  4. D target is always the document

Answer: A β€” target is the element that ACTUALLY triggered the event; currentTarget is the element the listener is attached to

Clicking a <span> inside a button makes target the span but currentTarget the button. This distinction is the key to event delegation.

targetcurrentTargetDelegation

Q7. hard

What is event BUBBLING?

  1. A An event fires on the target, then travels UP through each ancestor, triggering their handlers
  2. B Events go downward from document
  3. C Events repeat
  4. D Events fire twice

Answer: A β€” An event fires on the target, then travels UP through each ancestor, triggering their handlers

Click a button inside a div inside body: handlers fire on the button, then the div, then body, then document. Bubbling is what makes delegation possible.

BubblingPropagation

Q8. hard

What are the three phases of event propagation?

el.addEventListener("click", fn, true);   // capture phase
  1. A Capturing (down), target, then bubbling (up)
  2. B Start, middle, end
  3. C Click, hold, release
  4. D Only bubbling exists

Answer: A β€” Capturing (down), target, then bubbling (up)

The event descends from document to the target (capture), fires at the target, then bubbles back up. Passing true (or {capture: true}) to addEventListener runs your handler during the capture phase.

CapturingBubbling

Q9. hard

What is event DELEGATION?

list.addEventListener("click", (e) => {
  const btn = e.target.closest(".delete");
  if (!btn) return;
  btn.closest("li").remove();
});
  1. A Attaching ONE listener to a parent and using e.target to handle events from many children
  2. B Assigning events to another developer
  3. C Using multiple listeners per element
  4. D Removing listeners

Answer: A β€” Attaching ONE listener to a parent and using e.target to handle events from many children

Instead of a listener per row, put one on the container. It uses less memory and automatically covers elements added LATER - the standard pattern for dynamic lists.

DelegationPerformance

Q16. hard

How do you read all values from a form on submit?

form.addEventListener("submit", (e) => {
  e.preventDefault();
  const data = Object.fromEntries(new FormData(form));
  console.log(data.email);
});
  1. A const data = Object.fromEntries(new FormData(form))
  2. B form.values
  3. C form.data()
  4. D JSON.parse(form)

Answer: A β€” const data = Object.fromEntries(new FormData(form))

FormData collects every named field; fromEntries turns it into a plain object. Remember to call e.preventDefault() first.

FormDataForms

Q18. hard

What is the output order? parent.addEventListener("click", () => console.log("parent")); child.addEventListener("click", () => console.log("child")); // user clicks child

  1. A child then parent - the event bubbles upward
  2. B parent then child
  3. C Only child
  4. D Only parent

Answer: A β€” child then parent - the event bubbles upward

Default listeners run in the bubbling phase, starting at the target. Adding {capture: true} to the parent would make it fire FIRST instead.

BubblingOrder

Q20. hard

Why should scroll and resize handlers be throttled or debounced?

  1. A They fire extremely often, so heavy work in them causes janky, slow scrolling
  2. B They are disabled by default
  3. C They only fire once
  4. D No reason

Answer: A β€” They fire extremely often, so heavy work in them causes janky, slow scrolling

Scroll can fire dozens of times per second. Throttle limits the rate; debounce waits for a pause. For visibility detection, IntersectionObserver is better still.

PerformanceDebounceThrottle

Q22. hard

How do you trigger a custom event?

el.addEventListener("cart:add", e => console.log(e.detail.id));
el.dispatchEvent(new CustomEvent("cart:add", { detail: { id: 7 } }));
  1. A el.dispatchEvent(new CustomEvent("myEvent", { detail: data }))
  2. B el.trigger("myEvent")
  3. C el.fire("myEvent")
  4. D Custom events are impossible

Answer: A β€” el.dispatchEvent(new CustomEvent("myEvent", { detail: data }))

CustomEvent lets components communicate without direct coupling. The listener reads the payload from e.detail.

CustomEventComponent communication

Q25. hard

What does e.stopImmediatePropagation() add over stopPropagation()?

  1. A It also prevents OTHER listeners on the SAME element from running
  2. B Nothing extra
  3. C It removes the listener
  4. D It prevents the default action

Answer: A β€” It also prevents OTHER listeners on the SAME element from running

stopPropagation only halts the journey to ancestors; remaining handlers on the same element still fire. stopImmediatePropagation stops those too.

Propagation control

Q27. hard

Why might a listener attached in a loop capture the wrong value? for (var i = 0; i < 3; i++) btns[i].addEventListener("click", () => console.log(i));

  1. A var creates ONE shared binding, so every handler logs 3 - use let
  2. B Listeners cannot be added in loops
  3. C btns is undefined
  4. D It works correctly

Answer: A β€” var creates ONE shared binding, so every handler logs 3 - use let

The same closure trap as with setTimeout. Changing var to let gives each iteration its own binding, so the handlers log 0, 1 and 2.

Closureslet vs var

Q29. hard

Why remove event listeners when destroying a component?

const ac = new AbortController();
window.addEventListener("resize", fn, { signal: ac.signal });
ac.abort();   // removes it
  1. A Listeners keep references alive, preventing garbage collection - a memory leak
  2. B It is purely cosmetic
  3. C Listeners expire automatically
  4. D To reset the page

Answer: A β€” Listeners keep references alive, preventing garbage collection - a memory leak

Especially for listeners on window/document that reference removed elements. React's useEffect cleanup and AbortController exist for exactly this.

Memory leaksAbortController

Practice β€œEvents” as a quiz