Here is what will happen in the JavaScript execution environment:
document.body.style.backgroundColor will change its value to 'green'.
- A long-running process will run.
document.body.style.backgroundColor will change its value to 'red'.
It is unspecified how the changes in the backgroundColor property will affect the appearance of the page, if the JavaScript thread is blocked.
Here's an example. If you click the word hello, you will see a slight delay, and then the background will turn red:
function handleEvent(e){
document.body.style.backgroundColor = 'green';
longRunningFunction();
document.body.style.backgroundColor = 'red';
}
function longRunningFunction() {
for(var i=0; i<2000000000; ++i) { +i; }
}
document.body.addEventListener("click", handleEvent);
<div>hello</div>
This is because the browser's rendering engine that redraws in response to changes to CSS properties is blocked by the long-running blocking JavaScript function. This is not specified behavior, but rather an implementation reality for all browsers. See How can I force the browser to redraw while my script is doing some heavy processing? for a similar question.
I think any given browser could choose to run a separate redraw thread concurrent with the JavaScript thread, but I don't believe any major browsers currently do so. There may be race-condition complexities inherent in such an approach; I've never written a browser so I don't know.
If you want to show intermediate state, you can use a very quick setTiemout call after setting backgroundColor to green, to clear the JavaScript function stack and allow the renderer to redraw the page:
function handleEvent(e){
document.body.style.backgroundColor = 'green';
setTimeout(function() {
longRunningFunction();
document.body.style.backgroundColor = 'red';
}, 4);
}
This queues up the longRunningFunction and second color change to run in 4 milliseconds in the future. During that idle 4 milliseconds, the renderer has chance to redraw the page.