I am trying to better understand the relationship between how JavaScript updates DOM object.
Here is my html file index.html:
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<div id="container">old</div>
</body>
<script src="script.js"></script>
</html>
and here is my JavaScript file script.js,
const container = document.getElementById("container");
console.log(container, container.innerHTML);
container.innerHTML = "new";
console.log(container, container.innerHTML);
The console logs the same <div> tag but with different innerHTML which is quiet unexpected:
<div id="container">new</div> 'old'
<div id="container">new</div> 'new'
Therefore my 1st question is, what makes it possible for the console to print the same div elements but different innerHTML?
Secondly I made a small change to my script with setTimeout,
let timeout = 30;
setTimeout(() => {
container.innerHTML = "new";
console.log(container, container.innerHTML);
}, timeout);
Though container.innerHTML are always printed with different value, as expected, I found out that if the timeout value is above 35. The div tag is almost certainly printed differently with,
<div id="container">old</div> 'old'
<div id="container">new</div> 'new'
Then something I don't understand happens. When timeout is set below 10, it is almost certain that div tag are printed as,
<div id="container">new</div> 'old'
<div id="container">new</div> 'new'
When timeout is set somewhere between 10 and 30ish, the result toggles, meaning sometimes
<div id="container">new</div> 'old'
<div id="container">new</div> 'new'
and sometimes
<div id="container">old</div> 'old'
<div id="container">new</div> 'new'
Therefore my second question is, what causes this difference?
Much Appreciated.
Hopefully, I can respond to both questions with this:
Note that the innerHTML property is synchronous, meaning that the next line should not execute until that process finishes. However, the actual DOM must render again, and this happens separately (or asynchronously). The visual rendering in the DOM is not happening until after your stack of functions in JavaScript completes. Thus, your console.log() commands are retrieving information before the DOM has rendered with new HTML code.
You are seeing this with what you've shown in your second question. When you use a setTimeout() between 10 and 30ms, sometimes the DOM rendered again quick enough for your console.log() to now execute on the updated innerHTML. Of course, program and function execution across programming never completes at the exact same times for all kinds of reasons.
This thread may help you in understanding.