Reputation: 1306
This is a problem I've been struggling with for a while now. I've implemented an HTML5 progress
element like so:
<progress id="progress" value="0" max="100"></progress><output class="percent" id="percent">0</output><span class="prozent">%</span>
Suppose I update the value of progress
and percent
in a JS loop:
i = 0;
pBar = document.getElementById('progress');
pBar.value = i;//start at 0%
percent = 1;//set target for next progress bar update in %
//DO
do {
//IF(i > i_max) EXIT
//CALL VERLET
VERLET(i, x, v, a, time, const0, gamma, A_o, omega, dt);
x_plot[i] = [time[i], x[i]];
v_plot[i] = [time[i], v[i]];
a_plot[i] = [time[i], a[i]];
//i = i + 1
i = i + 1;
if (parseInt(i / i_max * 100, 10) === percent) {
pBar.value = percent;//update progress bar
document.getElementById('percent').innerHTML = percent;
percent = percent + 1;
}
//END DO
} while (i < i_max);
This is the relevant portion of my script. Please assume all variables are properly declared and initialized, and the script as whole is linted. A draft of the page can be found here.
I don't understand why the values of the progress
and output
elements are not updated until after the calculation is finished. Or this is what appears to happen. IE11(?) seems to show some updating when initially loading the page, but again doesn't update the progress bar for a new calculation without reloading.
Here is something along similar lines, but not using this modern method. I've taken a stab at getting this example to work, without success. This example, though better written I think, might shed some light on the problem.
Is it a timeout issue? Is there a simple jQuery method I could make use of? Any feedback on this problem will be appreciated.
Upvotes: 1
Views: 1966
Reputation: 1306
Here's how I got my progress bar to animate:
HTML
<progress id="progress" value="0" max="100"></progress><output class="percent" id="percent">0</output><span class="prozent">%</span>
JS
start = new Date().getTime();
//do stuff
end = new Date().getTime();
t = (end - start);
document.getElementById('progress').value = 0;
document.getElementById('percent').innerHTML = 0;
if (parseInt(t / 100.0, 10) <= 1) {
t = 1;//minimum update interval in ms
} else {
t = parseInt(t / 100.0, 10);//actual update interval in ms
}
go = setInterval(animate, t);
value = 0;
max = 100;
go = 0;
function animate() {
if (value >= max) {
clearInterval(go);
return;
}
value += 1;
document.getElementById('progress').value = value;
document.getElementById('percent').innerHTML = value;
if (value === max) {
clearInterval(go);
}
}
This script can be invoked when the page loads via <body onload="amp()">
or when prompted by the user with <input type="number" name="theta0" id="theta0" value="0.1" min="0.0" max="1.6" step="0.1" onchange="amp()">
. As you can see, the update interval is tied to the CPU clock time in ms since I can't update the DOM while in a while
loop. It's clunky, but it works.
Upvotes: 0
Reputation: 7336
As @epascarello says, you cant update the DOM in a while
loop.
Update it with an interval:
var interval = setInterval(function () {
VERLET(i, x, v, a, time, const0, gamma, A_o, omega, dt);
x_plot[i] = [time[i], x[i]];
v_plot[i] = [time[i], v[i]];
a_plot[i] = [time[i], a[i]];
i = i + 1;
if (parseInt(i / i_max * 100, 10) === percent) {
pBar.value = percent;//update progress bar
document.getElementById('percent').innerHTML = percent;
percent = percent + 1;
}
if (i < i_max) {
clearInterval(interval);
}
}, 100);
Upvotes: 1
Reputation: 2476
You can't do those kind of operations in a single while-loop.
What happens is the loop will run until it ends and you'll only be able to see the result when it finishes the operation.
For this kind of problems you should go for an asynchronous way.
function updateDom() {
// do stuff
setTimeout(updateDom, 500);
}
setTimeout(updateDom, 500);
Upvotes: 1