Reputation: 4159
I would like to animate an html page with something like this:
function showElements(a) {
for (i=1; i<=a; i++) {
var img = document.getElementById(getImageId(i));
img.style.visibility = 'visible';
pause(500);
}
}
function pause(ms) {
ms += new Date().getTime();
while (new Date() < ms){}
}
Unfortunately, the page only renders once javascript completes.
If I add
window.location.reload();
after each pause(500); invocation, this seems to force my javascript to exit. (At least, I do not reach the next line of code in my javascript.)
If I insert
var answer=prompt("hello");
after each pause(500), this does exactly what I want (i.e. update of the page) except for the fact that I don't want an annoying prompt because I don't actually need any user input.
So... is there something I can invoke after my pause that forces a refresh of the page, does not request any input from the user, and allows my script to continue?
Upvotes: 1
Views: 4778
Reputation: 97565
While the javascript thread is running, the rendering thread will not update the page. You need to use setTimeout
.
Rather than creating a second function, or exposing i
to external code, you can implement this using an inner function with a closure on a
and i
:
function showElements(a) {
var i = 1;
function showNext() {
var img = document.getElementById(getImageId(i));
img.style.visibility = 'visible';
i++;
if(i <= a) setTimeout(showNext, 500);
}
showNext();
}
If I add
window.location.reload();
after eachpause(500)
invocation, this seems to force my javascript to exit
window.reload()
makes the browser discard the current page and reload it from the server, hence your javascript stopping.
If I insert
var answer=prompt("hello");
after eachpause(500)
, this does exactly what I want.
prompt
, alert
, and confirm
are pretty much the only things that can actually pause the javascript thread. In some browsers, even these still block the UI thread.
Upvotes: 2
Reputation: 117314
function showElements(a,t) {
for (var i=1; i<=a; i++) {
(function(a,b){setTimeout(function(){
document.getElementById(getImageId(a)).style.visibility = 'visible'},a*b);}
)(i,t)
}
}
The t-argument is the delay, e.g. 500
Demo: http://jsfiddle.net/doktormolle/nLrps/
Upvotes: 0
Reputation: 10515
Javascript is inherently event-driven/non-blocking (this is one of the great things about javascript/Node.js). Trying to circumvent a built in feature is never a good idea. In order to do what you want, you need to schedule your events. One way to do this is to use setTimeout and simple recursion.
function showElements(a) {
showElement(1,a);
}
function showElement(i, max) {
var img = document.getElementById(getImageId(i));
img.style.visibility = 'visible';
if (i < max) {
setTimeout(function() { showElement(i+1, max) }, 500);
}
}
Upvotes: 1
Reputation: 7217
var i = 1;
function showElements(a) {
var img = document.getElementById(getImageId(i));
img.style.visibility = 'visible';
if (i < a) {
setTimeout(function() { showElements(a) }, 500);
}
i++;
}
showElements(5);
Upvotes: 0
Reputation: 887225
Your pause()
function sleeps on the UI thread and freezes the browser.
This is your problem.
Instead, you need to call setTimeout
to call a function later.
Upvotes: 1