Almost got my setTimeout to work

T

Terry

I am creating some simple animation and as am trying to use setTimeout
to run certain statements every 50 milliseconds.

My animation occurs in this function

function animator(letter)
{
var b,z,p;
var thedivs =
document.getElementById('A').getElementsByTagName('div');
alert("thedivs count = " + thedivs.length);
for (b=0,z=7;b<8;b++,z--)
for (p=0; p <= z; p++)
{
function f()
{
var d;
for (d=0; d < letter[z].length;d++)
{
thedivs[p*6+(letter[z][d])].style.backgroundImage =
"url(images/greendot.gif)";
if (p > 0)
thedivs[(p-1)*6+(letter[z][d])].style.backgroundImage =
"url(images/graydot.gif)";
}
}
setTimeout(f,p*50);
//f();
}
}

If I don't use setTimeout and just call the function directly (i.e.
f()) I get the image of the character 'A' which I want albeit almost
instantaneously.

When I try to use setTimeout the var z is -1 and my code falls apart.

Any suggestions as to how I could fix my problem?

The url to my page is http://theamazing.onlinewebshop.net/newanimate.htm

Thanks,
Terry
 
C

Captain Paralytic

I am creating some simple animation and as am trying to use setTimeout
to run certain statements every 50 milliseconds.

My animation occurs in this function

function animator(letter)
{
var b,z,p;
var thedivs =
document.getElementById('A').getElementsByTagName('div');
alert("thedivs count = " + thedivs.length);
for (b=0,z=7;b<8;b++,z--)
for (p=0; p <= z; p++)
{
function f()
{
var d;
for (d=0; d < letter[z].length;d++)
{
thedivs[p*6+(letter[z][d])].style.backgroundImage =
"url(images/greendot.gif)";
if (p > 0)
thedivs[(p-1)*6+(letter[z][d])].style.backgroundImage =
"url(images/graydot.gif)";
}
}
setTimeout(f,p*50);
//f();
}
}

If I don't use setTimeout and just call the function directly (i.e.
f()) I get the image of the character 'A' which I want albeit almost
instantaneously.

When I try to use setTimeout the var z is -1 and my code falls apart.

Any suggestions as to how I could fix my problem?

The url to my page ishttp://theamazing.onlinewebshop.net/newanimate.htm

Thanks,
Terry

When is the var z -1? You seem to be setting it to 7 at at least one
point.
 
T

Terry

I am creating some simple animation and as am trying to use setTimeout
to run certain statements every 50 milliseconds.
My animation occurs in this function
function animator(letter)
{
var b,z,p;
var thedivs =
document.getElementById('A').getElementsByTagName('div');
alert("thedivs count = " + thedivs.length);
for (b=0,z=7;b<8;b++,z--)
for (p=0; p <= z; p++)
{
function f()
{
var d;
for (d=0; d < letter[z].length;d++)
{
thedivs[p*6+(letter[z][d])].style.backgroundImage =
"url(images/greendot.gif)";
if (p > 0)
thedivs[(p-1)*6+(letter[z][d])].style.backgroundImage =
"url(images/graydot.gif)";
}
}
setTimeout(f,p*50);
//f();
}
}

When is the var z -1? You seem to be setting it to 7 at at least one
point

It is -1 right within the function f()

If I do alert("z = " + z) within function f() it will display z = -1.
I will throw the alert into the function so you could see what I mean.

It seems that by the time the function f runs (i.e 50 milliseconds
later) z would have been decremented to -1.

The url again is http://theamazing.onlinewebshop.net/newanimate.htm


Terry
 
H

Henry

I am creating some simple animation and as am trying to use
setTimeout to run certain statements every 50 milliseconds.

My animation occurs in this function

function animator(letter)
{
var b,z,p;
var thedivs =
document.getElementById('A').getElementsByTagName('div');
alert("thedivs count = " + thedivs.length);
for (b=0,z=7;b<8;b++,z--)
for (p=0; p <= z; p++)
{
function f()

There is no meaningful sense in which you can declare a function
within a loop. Strictly this is a syntax error y ECMA 262, and even
where is does not manifest an error the outcome is unlikely to be
consitent/useful/effective.
{
var d;
for (d=0; d < letter[z].length;d++)
{
thedivs[p*6+(letter[z][d])].style.backgroundImage =
"url(images/greendot.gif)";
if (p > 0)
thedivs[(p-1)*6+(letter[z][d])].style.backgroundImage
= "url(images/graydot.gif)";
}
}
setTimeout(f,p*50);
//f();
}
}

If I don't use setTimeout and just call the function directly (i.e.
f()) I get the image of the character 'A' which I want albeit
almost instantaneously.

When I try to use setTimeout the var z is -1 and my code falls apart.

Any suggestions as to how I could fix my problem?

It is best to understand closures before using them.

<URL: http://jibbering.com/faq/faq_notes/closures.html >
 
P

pr

Terry wrote:
[...]
for (b=0,z=7;b<8;b++,z--)
for (p=0; p <= z; p++)
{
function f()
{
var d;
for (d=0; d < letter[z].length;d++)
{
thedivs[p*6+(letter[z][d])].style.backgroundImage =
"url(images/greendot.gif)";
if (p > 0)
thedivs[(p-1)*6+(letter[z][d])].style.backgroundImage =
"url(images/graydot.gif)";
}
}
setTimeout(f,p*50);
//f();
}
}
[...]

You could make your life easier for yourself by not defining function
f() inside a loop. Define it somewhere else and make it accept thedivs,
letter, p, b and z as parameters. Then either

setTimeout(function(){f(param1, param2, etc...);}, p*50)

or
setTimeout('f(' + param1 + ', ' + param2 ... + ')', p*50)

In the course of doing so, you'll probably correct whatever problem
you're encountering.
 
T

Terry

Terry wrote:

[...]


for (b=0,z=7;b<8;b++,z--)
for (p=0; p <= z; p++)
{
function f()
{
var d;
for (d=0; d < letter[z].length;d++)
{
thedivs[p*6+(letter[z][d])].style.backgroundImage =
"url(images/greendot.gif)";
if (p > 0)
thedivs[(p-1)*6+(letter[z][d])].style.backgroundImage =
"url(images/graydot.gif)";
}
}
setTimeout(f,p*50);
//f();
}
}

[...]

You could make your life easier for yourself by not defining function
f() inside a loop. Define it somewhere else and make it accept thedivs,
letter, p, b and z as parameters. Then either

setTimeout(function(){f(param1, param2, etc...);}, p*50)

or
setTimeout('f(' + param1 + ', ' + param2 ... + ')', p*50)

In the course of doing so, you'll probably correct whatever problem
you're encountering.- Hide quoted text -
Thank you. I will try to implement your suggestions.

Terry
 
T

Terry

It seems that the paramters that are passed in must be strings or
numbers and not other objects.
I will have to try to alter my function a little.

Terry
 
T

Terry

I will have to try to alter my function a little.

I altered my function to not include objects other than strings and
numbers.
I am still having the problem with z being equal to -1 though

My code has been changed to:

function f(divs,biterator,piterator,ziterator)
{
var d;
//alert("z = " + ziterator);
alert("a length = " + a[7].length);

for (d=0; d < a[ziterator].length;d++)
{
divs[piterator*6+(a[ziterator][d])].style.backgroundImage =
"url(images/greendot.gif)";
//if (piterator > 0)
// divs[(piterator-1)*6+(a[ziterator][d])].style.backgroundImage
= "url(images/graydot.gif)";
}
}
function animator()
{
var b,z,p,t;
var thedivs =
document.getElementById('A').getElementsByTagName('div');
alert("thedivs count = " + thedivs.length);
t=0;

for (b=0,z=7;b<8;b++,z--)
for (p=0; p <= z; p++)
setTimeout(function() {f(thedivs,b,p,z);},p*50)
}

The url to the page is http://theamazing.onlinewebshop.net/newanimate.htm

Terry
 
P

pr

Terry said:
I altered my function to not include objects other than strings and
numbers.
I am still having the problem with z being equal to -1 though

My code has been changed to:

much easier to look at :)
function f(divs,biterator,piterator,ziterator)
{
var d;
//alert("z = " + ziterator);
alert("a length = " + a[7].length);

for (d=0; d < a[ziterator].length;d++)
{
divs[piterator*6+(a[ziterator][d])].style.backgroundImage =
"url(images/greendot.gif)";
//if (piterator > 0)
// divs[(piterator-1)*6+(a[ziterator][d])].style.backgroundImage
= "url(images/graydot.gif)";
}
}
function animator()
{
var b,z,p,t;
var thedivs =
document.getElementById('A').getElementsByTagName('div');
alert("thedivs count = " + thedivs.length);
t=0;

for (b=0,z=7;b<8;b++,z--)
for (p=0; p <= z; p++)
setTimeout(function() {f(thedivs,b,p,z);},p*50)
}

What you have here is a sort of closure, where the parameters to the
setTimeout function are evaluated when the timeout is up, not when the
function was defined. Since z has by this stage progressed in increments
from 7 to 0 and overshot (when the loop halted), it reads -1.

A short-term alternative is to declare thedivs as a global variable and
use the string form of setTimeout:

setTimeout("f(thedivs," + [b, p, z].join(",") + ")", p*50);

You might find a more durable answer by searching Google groups for
'setTimeout closure'. There's at least one long posting at

http://groups.google.co.uk/group/comp.lang.javascript/browse_thread/
thread/dbec49ac7828e0f3/60e842211d09bf19

which I hope to read later.
 
T

Terry

I altered my function to not include objects other than strings and
numbers.
I am still having the problem with z being equal to -1 though
My code has been changed to:

much easier to look at :)






function f(divs,biterator,piterator,ziterator)
{
var d;
//alert("z = " + ziterator);
alert("a length = " + a[7].length);
for (d=0; d < a[ziterator].length;d++)
{
divs[piterator*6+(a[ziterator][d])].style.backgroundImage =
"url(images/greendot.gif)";
//if (piterator > 0)
// divs[(piterator-1)*6+(a[ziterator][d])].style.backgroundImage
= "url(images/graydot.gif)";
}
}
function animator()
{
var b,z,p,t;
var thedivs =
document.getElementById('A').getElementsByTagName('div');
alert("thedivs count = " + thedivs.length);
t=0;
for (b=0,z=7;b<8;b++,z--)
for (p=0; p <= z; p++)
setTimeout(function() {f(thedivs,b,p,z);},p*50)
}

What you have here is a sort of closure, where the parameters to the
setTimeout function are evaluated when the timeout is up, not when the
function was defined. Since z has by this stage progressed in increments
from 7 to 0 and overshot (when the loop halted), it reads -1.

A short-term alternative is to declare thedivs as a global variable and
use the string form of setTimeout:

setTimeout("f(thedivs," + [b, p, z].join(",") + ")", p*50);

You might find a more durable answer by searching Google groups for
'setTimeout closure'. There's at least one long posting at

Thanks for responding. I do not understand. however, by using your
method how the values for the variables will not be messed up again.
Can you explain why your method will work?

I will look into the information conveyed at the link that you
provided.

Thanks,
Terry
 
P

pr

Terry said:
What you have here is a sort of closure, where the parameters to the
setTimeout function are evaluated when the timeout is up, not when the
function was defined. Since z has by this stage progressed in increments
from 7 to 0 and overshot (when the loop halted), it reads -1.

A short-term alternative is to declare thedivs as a global variable and
use the string form of setTimeout:

setTimeout("f(thedivs," + [b, p, z].join(",") + ")", p*50);
[...]
Thanks for responding. I do not understand. however, by using your
method how the values for the variables will not be messed up again.
Can you explain why your method will work?

window.setTimeout() has two forms. The original form takes a string as
its first parameter and evaluates this string when the timeout elapses.
The second form takes a function as its first parameter and offers
several advantages, one of which is causing your problem: the ability to
retain a reference to variables from the context in which the function
was created.

If you use the string form, setTimeout() will evaluate the string like
eval():

'f(thedivs, 0, 0, 7)'

and next time

'f(thedivs, 0, 1, 7)'

.... etc, treating any variable names it finds as global.

If you take the function route, it will each time execute:

f(whatever thedivs is now, whatever b is now, whatever p is now,
whatever z is now)

using the variables declared where the function was created.

There is a third alternative, however. You can point setTimeout() at a
method of a newly-created object, and rely on closure to access the
parameters it's created with:

window.setTimeout(new Action(thedivs, b, p, z).exec, p * 50);

...

function Action(fn, divs, bIterator, pIterator, zIterator) {
this.exec = function() {
fn(divs, bIterator, pIterator, zIterator);
};
}

It's more elegant but is almost certainly a lot slower (try it), and
since 50 milliseconds isn't a lot of time, I'd recommend:

window.setTimeout("f(thedivs," + b + "," + p + "," + z + ")", p * 50);

unless your researches turn up any better information.
 
T

Terry

window.setTimeout("f(thedivs," + b + "," + p + "," + z + ")", p * 50);

Thanks for clearing things up for me. I will to digest everything
soon.

I did try your call to setTimeout and unfortunately only some of the
animation occurred.


In the last little while I tried to do some reverse engineering.

I got rid of the setTimeout call to see the code execute and counted
the iterations that were taking place. I then decided to pass in the
index of those iterations into the setTimeout call. I then included
statements to figure out what the parameters would have been at each
of the calls to the function used within setTimeout.

It seems like it is going to work. I am writing a mapping function
that will take each value of the index and calculate what b,p, and z
would have been

i.e

function animator()
{
var t=0;
var z = 7;
var p;
var d;
var b;
var modfactor = 8;
var mods = -1;
function f()
{
thet = t++;
b = parseInt(thet / modfactor);
p = thet % modfactor;




if ((thet > 0) && (p == 0))
{
alert("WE HAVE MODULUS");

modfactor--;

}

z = 7 - b;
alert("t = " + thet + " b = " + b + " p = " + p + " z = " + z);

// use values of b, p, and z here

if (t < 36)
{
setTimeout(f,100)
}
};

f();
}

The values that I have calculated are slightly off. I will get it
right soon.

Thanks,
Terry
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top