Almost got my setTimeout to work

Discussion in 'Javascript' started by Terry, Sep 26, 2007.

  1. Terry

    Terry Guest

    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
     
    Terry, Sep 26, 2007
    #1
    1. Advertising

  2. On 26 Sep, 15:37, Terry <> wrote:
    > 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.
     
    Captain Paralytic, Sep 26, 2007
    #2
    1. Advertising

  3. Terry

    Terry Guest

    On Sep 26, 10:44 am, Captain Paralytic <> wrote:
    > On 26 Sep, 15:37, Terry <> wrote:
    >
    >
    >
    >
    >
    > > 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
     
    Terry, Sep 26, 2007
    #3
  4. Terry

    Henry Guest

    On Sep 26, 3:37 pm, Terry <> wrote:
    > 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 >
     
    Henry, Sep 26, 2007
    #4
  5. Terry

    pr Guest

    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.
     
    pr, Sep 26, 2007
    #5
  6. Terry

    Terry Guest

    On Sep 26, 11:20 am, pr <> wrote:
    > 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
     
    Terry, Sep 26, 2007
    #6
  7. Terry

    Terry Guest

    On Sep 26, 11:23 am, Terry <> wrote:
    > > setTimeout('f(' + param1 + ', ' + param2 ... + ')', p*50)

    >
    > > In the course of doing so, you'll probably correct whatever problem
    > > you're encountering.- Hide quoted text -

    >

    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
     
    Terry, Sep 26, 2007
    #7
  8. Terry

    Terry Guest

    On Sep 26, 11:47 am, Terry <> wrote:
    > 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
     
    Terry, Sep 26, 2007
    #8
  9. Terry

    pr Guest

    Terry wrote:
    > On Sep 26, 11:47 am, Terry <> wrote:
    >> 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:


    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.
     
    pr, Sep 26, 2007
    #9
  10. Terry

    Terry Guest

    On Sep 26, 2:45 pm, pr <> wrote:
    > Terry wrote:
    > > On Sep 26, 11:47 am, Terry <> wrote:
    > >> 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:

    >
    > 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
     
    Terry, Sep 26, 2007
    #10
  11. Terry

    pr Guest

    Terry wrote:
    > On Sep 26, 2:45 pm, pr <> wrote:

    [...]
    >> 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.
     
    pr, Sep 27, 2007
    #11
  12. Terry

    Terry Guest

    On Sep 27, 7:27 am, pr <> wrote:

    > 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
     
    Terry, Sep 27, 2007
    #12
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?RQ==?=

    javascript setTimeout does not work

    =?Utf-8?B?RQ==?=, May 2, 2006, in forum: ASP .Net
    Replies:
    4
    Views:
    8,843
    =?UTF-8?B?R8O2cmFuIEFuZGVyc3Nvbg==?=
    May 2, 2006
  2. Robert S
    Replies:
    2
    Views:
    135
    Robert S
    Jul 23, 2006
  3. danep
    Replies:
    1
    Views:
    179
    danep
    Jul 23, 2007
  4. Replies:
    4
    Views:
    233
  5. Aaron Fude

    setTimeout doesn't work

    Aaron Fude, Apr 6, 2008, in forum: Javascript
    Replies:
    3
    Views:
    188
    Lasse Reichstein Nielsen
    Apr 6, 2008
Loading...

Share This Page