One click listener on a task list reads the clicked button and updates an accessible status output.

Program

Event delegation keeps one listener on the list instead of attaching a separate listener to every button.

One parent listener can react because the event carries its target.Event delegation pathPinned path for one Done button clicktarget: the clicked button; listener: the parent listdocumenttask listbuttontask liststatusrole=status updates onceOne parent listener can react because the event carries its target.
Figure: A delegated click moves through the event path. Model source: books/javascript-client/02events_forms/list_event_delegation/diagrams/event_path.semantic.json.
list_event_delegation.html
<ul id="tasks">
  <li><button data-task="Pack">Pack</button></li>
  <li><button data-task="Ship">Ship</button></li>
</ul>
<output id="status" role="status">No task selected</output>
<script>
  const tasks = document.querySelector("#tasks");
  const status = document.querySelector("#status");
  tasks.addEventListener("click", event => {
    const button = event.target.closest("button[data-task]");
    if (!button) return;
    status.textContent = button.dataset.task + " selected";
  });
</script>
event delegation A parent listener can handle clicks from child controls by inspecting the event target.
status output role="status" gives the result a simple accessible update area.