Recommand · May 26, 2021 0

How is a click event being registered when the dom is blocked?

When I click on a button in my HTML page at a moment when my JavaScript code is looping for 3 seconds, nothing happens at the moment. The DOM isn’t responsive. I assume it’s blocked until my JavaScript code finishes execution. But after 3 seconds I get the "button click event" and "click event" in my console logs.

How is the DOM registering events, even when it’s blocked by my JavaScript code.

// long running function
function waitThreeSeconds() {
    var ms = 3000 + new Date().getTime();
    while (new Date() < ms){}
    console.log('finished function');
}

function clickHandler() {
    console.log('click event!');   
}

function buttonClickHandler() {
    console.log('button click event!');   
}

// When the page is displayed, start "busy loop"
setTimeout(waitThreeSeconds, 100);

// listen for the click event
document.addEventListener('click', clickHandler);
const button = document.querySelector('button')
button.addEventListener('click', buttonClickHandler);
<button>click me!!</button>

When you have bound a handler to a click event, and that click event happens, the DOM will place a job, i.e. the call to your event handler, in JavaScript’s event queue. Note that this happens "under the hood" — this is not JavaScript code doing that, but compiled (lower level) code. That process may execute concurrently with executing JavaScript.

If the JavaScript engine is busy executing your code, that job just sits there in the queue. When your JavaScript code finally finishes execution, and thus its call stack is empty, then the engine will process the next job it finds in the event queue. The job is then executed. In this case the job is the relevant click handler.

In your example case, two jobs will be added to the queue when you click the button, as there are two handlers for that click event (on the button and on the document). When you click beside the button, on the page, there will be one job added to the queue.

When JavaScript is not executing code at the moment of the click, then the JavaScript engine is continually monitoring the queue, and so it will "react" instantly to a click, executing the jobs it finds in the queue.