Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Javascript > setTimeOut

Reply
Thread Tools

setTimeOut

 
 
Frances Del Rio
Guest
Posts: n/a
 
      09-24-2004

this code is supposed to flip imgs at intervals of one second, but it
flipps them much faster, it seems it flips them all in that first
second, the more seconds the faster it flips them, instead of the other
way around... (I mean it seems to me the more seconds I put in there the
more seconds should go by betw. flips... each photo is in a div, each
div has a z-index of 0, 1, 2, etc..)

http://www.francesdelrio.com/cassini
(pls reload a few times, my stuff loads a bit slow b/c my site is hosted
abroad, their int'l traffic is slower..)

code:

var photos = new
Array("one","two","three","four","five","six","sev en","eight")
function flip() {
for (i=1; i < photos.length; i++) {
var photoDiv = eval('document.getElementById(' + "photos[i]" + ')')
var doIt = photoDiv.style.visibility = "visible"
setTimeout("doIt",1000)
}
}

thank you.. Frances

 
Reply With Quote
 
 
 
 
J. J. Cale
Guest
Posts: n/a
 
      09-24-2004

"Frances Del Rio" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
>
> this code is supposed to flip imgs at intervals of one second, but it
> flipps them much faster, it seems it flips them all in that first
> second, the more seconds the faster it flips them, instead of the other
> way around... (I mean it seems to me the more seconds I put in there the
> more seconds should go by betw. flips... each photo is in a div, each
> div has a z-index of 0, 1, 2, etc..)
>
> http://www.francesdelrio.com/cassini
> (pls reload a few times, my stuff loads a bit slow b/c my site is hosted
> abroad, their int'l traffic is slower..)
>
> code:
>
> var photos = new
> Array("one","two","three","four","five","six","sev en","eight")
> function flip() {
> for (i=1; i < photos.length; i++) {

will not reference the first array element
> var photoDiv = eval('document.getElementById(' + "photos[i]" + ')')

eval is unnecessary and in general shouldn't be used to return object
references as such
var photoDiv = document.getElementById(photos[i]);
> var doIt = photoDiv.style.visibility = "visible"

doIt always = "visible"
> setTimeout("doIt",1000)

first parameter wants a function reference or a valid expression. Further
the timeout won't work the way I think you intend since the loop doesn't
stoop for 1 second when you call setTimeout. It just keeps falling through
the loop and all your images will be shown at once. If Dr J is listening he
is an expert on this type of thing but you better explain what you're trying
to do. e.g. turn images on/off at intervals; turn cards in a series at one
second intervals.
> }
> }

depending on what you're doing, the use of the array and the Ids is
unnecessary. You could wrap them in a div with id="wrapper" and loop through
them using wrapper.children(i) to reference each object. I assume from your
code that you have each image in a separate div. This is not always a good
idea again depending on what you're trying to achieve. If it's positioning
you can achieve the same or better results just using the image tags or
<p><img ... or <span><img
Hope this helps. Jimbo
>
> thank you.. Frances
>



 
Reply With Quote
 
 
 
 
Frances Del Rio
Guest
Posts: n/a
 
      09-25-2004


J. J. Cale wrote:
> "Frances Del Rio" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
>
>>this code is supposed to flip imgs at intervals of one second, but it
>>flipps them much faster, it seems it flips them all in that first
>>second, the more seconds the faster it flips them, instead of the other
>>way around... (I mean it seems to me the more seconds I put in there the
>>more seconds should go by betw. flips... each photo is in a div, each
>>div has a z-index of 0, 1, 2, etc..)
>>
>>http://www.francesdelrio.com/cassini
>>(pls reload a few times, my stuff loads a bit slow b/c my site is hosted
>>abroad, their int'l traffic is slower..)
>>
>>code:
>>
>> var photos = new
>>Array("one","two","three","four","five","six","s even","eight")
>> function flip() {
>> for (i=1; i < photos.length; i++) {

>
> will not reference the first array element
>
>> var photoDiv = eval('document.getElementById(' + "photos[i]" + ')')

>
> eval is unnecessary and in general shouldn't be used to return object
> references as such
> var photoDiv = document.getElementById(photos[i]);
>
>> var doIt = photoDiv.style.visibility = "visible"

>
> doIt always = "visible"
>
>>setTimeout("doIt",1000)

>
> first parameter wants a function reference or a valid expression. Further
> the timeout won't work the way I think you intend since the loop doesn't
> stoop for 1 second when you call setTimeout. It just keeps falling through
> the loop and all your images will be shown at once. If Dr J is listening he
> is an expert on this type of thing but you better explain what you're trying
> to do. e.g. turn images on/off at intervals; turn cards in a series at one
> second intervals.
>
>> }
>> }

>
> depending on what you're doing,


thank you very much for yr help.. this is simply a learning exercise...
(need to learn how to implement my own loops from scratch..) I simply
want imgs to flip every 2 seconds or so for ever, that's it.... I
implemented yr code (but don't understand 'doIt always = "visible"',
wasn't sure about that line, left it out..) now cycle goes thru once
then stops.... I want it to start over when it finishes, like a slide
show that reaches the end then starts again... I know I need to call
function again once it's done, but not sure how.. called function again
right outside loop (inside function) but still went thru loop only
once.. (and then get an "out of memory" error, had never seen this..)

now am trying same w/rollovers instead of hide/show divs...

var photos = new
Array("one","two","three","four","five","six","sev en","eight")
function flip() {
for (i=1; i < photos.length; i++) {
var doIt = "cassini.src = 'images/" + photos[i] + ".jpg'"
// one.jpg, two.jpg, three.jpg, etc..
setTimeout("doIt",i*1000)
}
}

here I get NOTHING.... (I see a flicker.. like imgs flip really fast or
something..) I understand very well the concept of loops, what I have a
hard time with usu. is organizing stmts inside the loop... again, thank
you very much for yr help.. Frances

 
Reply With Quote
 
Michael Winter
Guest
Posts: n/a
 
      09-25-2004
On Fri, 24 Sep 2004 23:20:50 -0400, Frances Del Rio <(E-Mail Removed)>
wrote:

[snip]

> thank you very much for yr help..

^^

Please don't use abbreviations like that. Saving two keystrokes is hardly
worth the loss of readability.

[snip]

> I implemented yr code (but don't understand
> 'doIt always = "visible"', wasn't sure about that line, left it
> out..)


He was saying that in your code, 'doIt' always equalled 'visible'. The
statement in question was:

var doIt = photoDiv.style.visibility = "visible"

First, the visibility property of the photoDiv style object is assigned
'visible'. Next, doIt is assigned the value of the visibility property.
Considering that you want doIt to be a function reference for it to be of
any real use with setTimeout, the statement above is not what want.

[snip]

> called function again right outside loop (inside function) but still
> went thru loop only once.. (and then get an "out of memory"
> error, had never seen this..)


That would be a stack overflow and a pattern called recursion. Recursion -
calling a function from within that function - can be a useful thing. For
example, nested data, such as that found in the document tree, can be
examined by calling a function recursively, passing in a different branch
on each invocation. However, recursive calls take up memory as the system
needs to remember the state of earlier function calls. This state is
stored on the stack (in most languages on the PC). If you don't set a
condition whereby recursion stops, it will keep going until you run out of
memory.

> now am trying same w/rollovers instead of hide/show divs...
>
> var photos = new
> Array("one","two","three","four","five","six","sev en","eight")


Define arrays with literals:

var photos = ['one', 'two', 'three', 'four', 'five', 'six',
'seven', 'eight'];

> function flip() {
> for (i=1; i < photos.length; i++) {


This will cause the first image to be skipped. Arrays are zero-order (they
start at index zero). Also, be sure to declare that variable, i, with the
var keyword. If you don't it will become global.

for (var i = 0; i < photos.length; i++) {

This isn't a fix; just a tip.

> var doIt = "cassini.src = 'images/" + photos[i] + ".jpg'"
> // one.jpg, two.jpg, three.jpg, etc..
> setTimeout("doIt",i*1000)
> }
> }
>
> here I get NOTHING.... (I see a flicker.. like imgs flip really fast or
> something..) I understand very well the concept of loops, what I have a
> hard time with usu. is organizing stmts inside the loop... again, thank
> you very much for yr help.. Frances


The flow of that function has become quite confused. When the function is
called, a loop is encountered with no code to halt it. That immediately
implies that the entire set of images will be processed. That's why you
saw all of the images flash into view with previous versions. All that
happens here is string concatenation (and assignment), and a call to
setTimeout that will do nothing useful.

var j = 0,
photos = ['one', 'two', 'three', 'four', 'five', 'six',
'seven', 'eight'];

function flip() {
document.images['cassini'].src = 'images/' + photos[j] + '.jpg';
j = (j + 1) % photos.length;
}
// Call onload:
setInterval(flip, 1000);

This is a simple version of what you want to achieve. setInterval will
call flip approximately every second. When it does, the first statement
will change the source of the IMG element, cassini, and increment the
index variable, j. The modulus (%) ensures that the value of j stays
within the range 0 <= j < 8.

However, this code pollutes the global namespace. It also looks-up a
reference to the IMG, cassini, and the length property of the photos array
on every invocation of flip.

window.onload = function() {
var i = document.images['cassini'],
j = 0,
p = ['one', 'two', 'three', 'four', 'five', 'six', 'seven',
'eight'],
n = p.length;

function flip() {
i.src = 'images/' + p[j] + '.jpg';
j = (j + 1) % n;
}
flip.toString = function() {return 'flip()';};

setInterval(flip, 1000);
};

That's quite a transformation.

The first thing to note is the external function expression, function()
{ ... }. You can think of this just like any other function, except it
doesn't have a name. What this does is produce a new scope level. As with
all functions, the local variables declared here aren't accessible outside
of the function. This means you can name variables, that would normally be
global, anything you like and not worry about them clashing with other
variables.

Inside the function, things are much like they were last time, with two
slight differences:

1) A reference to the IMG element, cassini, has been assigned to the
variable, i. This allows it to be looked-up once only, rather than
repeatedly.
2) Similarly, the length property of the array of filenames has been
stored in n. Like the reference to cassini, it doesn't change, so why keep
looking it up?

There's a third difference, which follows after the declaration of flip.
All functions and objects have a method called toString. Whenever a string
value is required, and an object or function is given, this method is
called and string that represents that object is returned[1]. The
setInterval function, like setTimeout, can accept two types as its first
argument. A function reference, and a string. Older browsers only accept a
string. Giving the function, flip, a toString method means that browsers
can convert the argument to a form they can use. This is explained in the
FAQ notes:

<URL:http://www.jibbering.com/faq/faq_notes/misc.html#mtSetTI>

I should also briefly explain the mechanism, as a whole, that allows this
to work. When a function has returned, local variables are usually
destroyed. However, this doesn't happen with the outer function above. The
reason is the position of the inner function, flip. flip references the
local variables of the outer function, so they remain in memory; flip
forms a closure. Closures have many applications, too numerous to list
here. A detailed explanation of them is also present in the FAQ notes:

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

I hope that was understandable, or at least gives you the functionality
that you want. If you need to execute other things when the document loads
(the code above will overwrite it), change the first line of my code from

window.onload = function() {

to

function functionName() {

giving the function any name you want. You can then place the function
amongst your other onload code.

Good luck,
Mike


[1] The actual value can vary, depending on the implementation and the
type of object.

--
Michael Winter
Replace ".invalid" with ".uk" to reply by e-mail.
 
Reply With Quote
 
Yann-Erwan Perio
Guest
Posts: n/a
 
      09-25-2004
Michael Winter wrote:

> window.onload = function() {
> var i = document.images['cassini'],
> j = 0,
> p = ['one', 'two', 'three', 'four', 'five', 'six', 'seven',
> 'eight'],
> n = p.length;
>
> function flip() {
> i.src = 'images/' + p[j] + '.jpg';
> j = (j + 1) % n;
> }
> flip.toString = function() {return 'flip()';};
>
> setInterval(flip, 1000);
> };
>
> That's quite a transformation.


....and a better one as well, but with a slight mistake; the flip
function should be global if you want the toString fallback to be
executable (string argument for the setInterval methods are evaluated in
a global context).

Therefore what about replacing
function flip() {
by
flip = function() {
?


Regards,
Yep.
 
Reply With Quote
 
Yann-Erwan Perio
Guest
Posts: n/a
 
      09-25-2004
Yann-Erwan Perio wrote:

> Michael Winter wrote:


> Therefore what about replacing
> function flip() {
> by
> flip = function() {
> ?


Nah, forget it, that wouldn't work - there no way to add the fallback if
using closures.

 
Reply With Quote
 
Michael Winter
Guest
Posts: n/a
 
      09-25-2004
On Sat, 25 Sep 2004 11:13:45 +0200, Yann-Erwan Perio
<(E-Mail Removed)> wrote:

[snip]

> Nah, forget it, that wouldn't work


*slaps head*

No, of course not. Stupid mistake on my part.

> there no way to add the fallback if using closures.


By exposing the function, it is possible:

function initFlip() {
var i = document.images['cassini'],
j = 0,
p = ['one', 'two', 'three', 'four', 'five', 'six', 'seven',
'eight'],
n = p.length;

function flip() {
i.src = 'images/' + p[j] + '.jpg';
j = (j + 1) % n;
}
flip.toString = function() {return 'initFlip.flip()';};

initFlip.flip = flip;

setInterval(flip, 1000);
};
window.onload = initFlip;

It seems hack-ish, though. But it does work.

Thanks for pointing that out,
Mike

--
Michael Winter
Replace ".invalid" with ".uk" to reply by e-mail.
 
Reply With Quote
 
Yann-Erwan Perio
Guest
Posts: n/a
 
      09-25-2004
Michael Winter wrote:

>> Nah, forget it, that wouldn't work

>
> *slaps head*


That looked painful

>> there no way to add the fallback if using closures.

>
> By exposing the function, it is possible:


Sorry, I meant using the closure in the original construct, not with
closures in general (with which alsmost everything is possible) - using
an outer function, as you've just proposed, is indeed the best way,
since you can still take advantage of the flip closure in normal mode.

> It seems hack-ish, though. But it does work.


No no no, it's not hackish, that's just how javascript can be written,
and most of the time, should be written (IMHO).


Cheers,
Yep.
 
Reply With Quote
 
Michael Winter
Guest
Posts: n/a
 
      09-25-2004
On Sat, 25 Sep 2004 12:15:50 +0200, Yann-Erwan Perio
<(E-Mail Removed)> wrote:

[snip]

> Sorry, I meant using the closure in the original construct [...]


I know, but the OP might have been confused and may not have worked out
how to reach a solution.

>> It seems hack-ish, though. But it does work.

>
> No no no, it's not hackish, that's just how javascript can be written,
> and most of the time, should be written (IMHO).


The original just seemed cleaner. Self-contained.

Mike

--
Michael Winter
Replace ".invalid" with ".uk" to reply by e-mail.
 
Reply With Quote
 
Yann-Erwan Perio
Guest
Posts: n/a
 
      09-25-2004
Michael Winter wrote:

>> No no no, it's not hackish, that's just how javascript can be
>> written, and most of the time, should be written (IMHO).

>
> The original just seemed cleaner. Self-contained.


That's certainly true, and is indeed what should be presented if the OP
doesn't know much about javascript; however the second is much more
subtile, and tackles issues not considered in the first attempt.

I was however simply raising myself against the term "hackish", which
implies trying to patch/break into an inability of the language The
use you've made of javascript wasn't therefore in my view hackish but
rather completely normal, using regular javascript-specific optimisation
techniques to achieve its goal.

Anyway, your post, by presenting the two versions and providing leads on
how to deal with the second one, was an excellent one.


Cheers,
Yep.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
javascript setTimeout does not work =?Utf-8?B?RQ==?= ASP .Net 4 05-02-2006 08:21 PM
setTimeout JR HTML 3 04-15-2004 12:07 PM
settimeout j van c HTML 5 12-07-2003 09:08 AM
socket settimeout ? Colin Brown Python 0 12-03-2003 12:28 AM
Smart navigation and js setTimeout Andy Pickering ASP .Net 1 10-27-2003 10:51 AM



Advertisments