Reputation: 17173
my eval()
call is fairly intensive and takes about a second to generate each solution.
Therefore it takes about a second to generate each paragraph element (which I then append to the dom - document.getElementById('project_euler_solutions').appendChild(p);
).
Therefore I expected each paragraph to appear on the webpage about a second apart. (so after about 40 seconds I would have 40 paragraphs say).
However, when I click the button, Nothing happens for 40 seconds, and then all the solutions appear at once.
How come it waits for all of them to finish before it updates the dom?
I thought each paragraph would appear as soon as it was appended to the dom
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<script src="http://ajax.microsoft.com/ajax/jquery/jquery-1.6.2.min.js"></script>
<script src="/statics/project_euler.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("button").click(function(){
for (var i in window) {
if (i.slice(0,5) == "solve") {
var p = document.createElement('p');
p.innerHTML = "running: " + i;
document.getElementById('project_euler_solutions').appendChild(p);
var p = document.createElement('p');
p.innerHTML = "Solution: " + eval(i + "()");
document.getElementById('project_euler_solutions').appendChild(p);
}
}
});
});
</script>
</head>
<body>
<div id="project_euler_solutions"><button>Calculate solutions</button></button></div>
</body>
</html>
Upvotes: 3
Views: 2300
Reputation: 140220
Force a reflow:
$(document).ready(function(){
$("button").click(function(){
for (var i in window) {
if (i.slice(0,5) == "solve") {
var p = document.createElement('p');
p.innerHTML = "running: " + i;
document.getElementById('project_euler_solutions').appendChild(p);
var p = document.createElement('p');
p.innerHTML = "Solution: " + eval(i + "()");
document.getElementById('project_euler_solutions').appendChild(p);
document.getElementById('project_euler_solutions').offsetHeight; //Force a reflow
}
}
});
});
You can also setTimeout between the drawings:
var keys = Object.keys(window).filter(function(i){
return i.slice(0,5) === "solve";
});
(function (i){
(function k(){
var p = document.createElement('p');
p.innerHTML = "running: " + keys[i];
document.getElementById('project_euler_solutions').appendChild(p);
var p = document.createElement('p');
p.innerHTML = "Solution: " + eval(keys[i] + "()");
document.getElementById('project_euler_solutions').appendChild(p);
if( i++ < keys.length - 1 ) {
setTimeout(k, 0);
}
})()
})(0)
Upvotes: 1
Reputation: 254906
Javascript runs in the same thread as UI, so you need to give the control back for the DOM to re-draw all the changes.
Upvotes: 5