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 pletes.
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?
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 pletes.
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?
Share Improve this question edited Sep 5, 2012 at 19:55 Eric 97.8k54 gold badges255 silver badges389 bronze badges asked Sep 5, 2012 at 19:41 LoloLolo 4,1796 gold badges45 silver badges55 bronze badges 1-
Are you looking for something like the
setTimeOut
function? electrictoolbox./using-settimeout-javascript – Chase Commented Sep 5, 2012 at 19:45
5 Answers
Reset to default 2While 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.
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.
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);
}
}
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);
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/doktormolle/nLrps/