DOM event questions are about where an event starts, how it travels and who owns each listener's lifetime. A small page can behave correctly on its first click and still accumulate duplicate behavior after setup runs again.

This browser example uses one delegated listener on an existing list. It is a local teaching fragment, not a React or Angular component.

How does one listener handle several rows?

<ul id="parcels">
  <li><button type="button" data-parcel="A">Select A</button></li>
  <li><button type="button" data-parcel="B">Select B</button></li>
</ul>
<output id="selection"></output>
<script>
  const list = document.querySelector('#parcels');
  const output = document.querySelector('#selection');
  function choose(event) {
    const button = event.target.closest('button[data-parcel]');
    if (!button || !list.contains(button)) return;
    output.textContent = button.dataset.parcel;
  }
  list.addEventListener('click', choose);
  function cleanup() {
    list.removeEventListener('click', choose);
  }
</script>

A click on a button can bubble to the list. The handler finds the relevant button and confirms that it belongs to the expected container. Newly added matching rows can use the same listener without registering a handler on each row.

What is the difference between target and currentTarget?

Target identifies where the event originated, subject to details such as shadow-DOM retargeting. CurrentTarget identifies the element whose listener is currently handling it. In the example, the listener belongs to the list even when the click starts on a button inside it.

If a button contains a span, the target may be that span. Looking for the nearest matching button is more robust than assuming the target itself always has the data attribute. Still, test the actual markup and boundary you support.

Why must removal use the same listener?

Two separately created arrow functions are different function objects even if their bodies contain the same text. Registering one and trying to remove the other does not remove the original registration. Keep a reference to the handler or use an appropriate abort signal to own the registration lifetime.

When matching a registration for removal, the capture setting also matters. Do not describe all listener options as interchangeable identity keys. Read the exact matching rules for the API you use.

Do stopPropagation and preventDefault do the same thing?

No. Preventing a default action and stopping further event propagation are different decisions. A link's navigation is a default action; a parent listener receiving the event is propagation. Blocking one does not automatically describe the state of the other.

Use either only when it supports the interaction's contract. Broadly stopping events can break surrounding behavior, and some passive-listener situations do not permit preventing the default action.

How can duplicate behavior appear?

Repeated setup can create new handler functions and register all of them. A later click then performs the action more than once. A cleanup path, a clear setup lifetime and a test that mounts or initializes twice can expose the problem.

Do not assume that a successful single-click test proves the lifecycle is correct. Test what happens after leaving and returning to the feature, replacing rows or disposing the owning object.

Practice checks

  • Click both original rows and a newly appended row.
  • Click nested text within a button.
  • Click unrelated space in the list.
  • Run cleanup and confirm later clicks no longer perform the action.
  • Explain which behavior belongs to event propagation and which belongs to your own handler.

The useful lesson is ownership. A listener needs an owner and an end to its lifetime just as a timer or connection does. Delegation reduces registrations in some designs, but it does not remove the need for a correct cleanup policy.

References and next practice

developer.mozilla.org — js events

Browse interview topics · Practise a question in Interview Challenge · How to Answer Technical Interview Questions Out Loud