What an event is
An event is a signal that something happened on the page: a click, a key press, a form being sent. The browser describes it in an event object and delivers it through the DOM tree, the objects built from the HTML.
Adding a listener
The script runs once, top to bottom. document.querySelector("#todo") finds the element whose id is todo: the <ul> that holds both rows. const keeps it in list.
addEventListener("click", function) attaches a listener to the list: run this function whenever a click event reaches the list. The function, lines 3 to 6, does not run yet. There is no listener on the rows or the buttons.
The event's trip
You click the Done button in the Milk row. The browser makes an event object. Its type is "click" and its target is the element you clicked: that button. Its currentTarget is null until the trip starts.
The event travels from the top of the tree down to its target: document, the list, the row, the button. This is the capture phase. currentTarget names each element it passes. Our listener waits for the way back up.
A click bubbles: from the button it travels back up, through the row to the list. The list has a listener for click, so the browser calls it. Now, and only now, the function from line 2 runs.
The listener runs
event.target is still the button you clicked. closest("li") starts there and walks up to the nearest <li>: the Milk row. A click on the list itself, outside any row, finds none, so line 4 returns early.
classList.toggle("done") adds the class done to the row, or removes it if it is already there. The style rule .done draws a line through the text, so the browser shows Milk crossed out.
console.log(event.target.tagName) prints BUTTON. The listener sits on the list, but event.target is where the click happened. event.currentTarget is the list, the element whose listener is running.
Event delegation
Click Done on Bread. A new click event bubbles up to the same listener, which crosses out Bread and prints BUTTON again. One listener on a parent handles all its children, even rows added later: this is event delegation.
What happens
// step 1/10 · event
event a signal: something happened
examples click, keydown, submit, input
object the browser describes it in an Event
listener a function that waits for one type
page todo.html: a list with two rows,
each with a Done button
The real path is longer: window, document, html, body, ul, li, button. The figure leaves out window, html and body; they have no listeners here, so nothing changes. event.stopPropagation() stops the trip at the current element, so parents further up never hear the event. event.preventDefault() is different: it cancels the browser's own action, such as following a link or sending a form.