The call stack finishes what it started
The common read: a click that happens while a function is running is either lost entirely or runs its handler the instant the click occurs.
The call stack is where JavaScript keeps track of which function is running and who called it. One function runs at a time. Until it returns, the only code that can run is code it calls itself. Nothing preempts it: not a timer, not a network response, not a click. This rule is called run-to-completion, and it holds for every function, all the time, with no exception for urgent work.
A handler that is ready to run is not the same as a handler that is running. When the user clicks, the browser does not put the click handler on the stack. It puts the handler in the task queue, the list of work waiting for the stack to be free. Only when the running function returns and the stack is empty does the event loop hand the stack to the next task in line.
That is why the click in the first question is neither lost nor run early. longSyncTask() owns the stack for its full 300ms, and done belongs to the same running script, so the click handler runs after both.

