setTimeout( ) javascript question

N

nikki_herring

I am using setTimeout( ) to continuously call a function that randomly
rotates/displays 2 images on a page. The part I need help with is the
second image should rotate 3 seconds after the first image rotates. I
cannot figure out how to accomplish the 3 second delay. My code is
pasted below:

function randPic(){
randPic1();
randPic2();

}

function randPic1(){
picIndex = picIndex + 1;
if (picIndex>=middlepics.length)
picIndex = 0;
d.images["pic1"].src="images/middle/"+middlepics[picIndex];
d.images["pic1"].alt=middlealts[picIndex];

timerID=setTimeout("randPic1()",3700);
}

function randPic2(){
bottomPicIndex = bottomPicIndex + 1;
if (bottomPicIndex>=bottompics.length)
bottomPicIndex = 0;
d.images["pic2"].src="images/
bottom/"+bottompics[bottomPicIndex];
d.images["pic2"].alt=bottomalts[bottomPicIndex];

timerID=setTimeout("randPic2()",5500);
}

The randPic( ) function is called in the onLoad event of the body tag.
Any ideas you may have would be greatly appreciated.
 
E

Evertjan.

wrote on 13 feb 2007 in comp.lang.javascript:
I am using setTimeout( ) to continuously call a function that randomly
rotates/displays 2 images on a page. The part I need help with is the
second image should rotate 3 seconds after the first image rotates. I
cannot figure out how to accomplish the 3 second delay. My code is
pasted below:

function randPic(){
randPic1();
randPic2();

}

function randPic(){
randPic1();
setTimeout('randPic2()',3000);
}

<body onload="randPic();">

or:

<body onload="setTimeout('randPic2()',3000);randPic1();">
 
N

Newbie

wrote on 13 feb 2007 in comp.lang.javascript:




function randPic(){
randPic1();
setTimeout('randPic2()',3000);
}

<body onload="randPic();">

or:

<body onload="setTimeout('randPic2()',3000);randPic1();">


Thanks. I tried both of these options and they worked except there is
some point at which both images rotate at the same time (which is what
we are trying to avoid). Do you know of a way to prevent this from
happening?
 
L

Lee

Newbie said:
Thanks. I tried both of these options and they worked except there is
some point at which both images rotate at the same time (which is what
we are trying to avoid). Do you know of a way to prevent this from
happening?

Have each one schedule the other to change, instead of scheduling
itself to change.


--
 
E

Evertjan.

Newbie wrote on 13 feb 2007 in comp.lang.javascript:
On Feb 13, 12:32 pm, "Evertjan." <[email protected]>
wrote: [....]
<body onload="setTimeout('randPic2()',3000);randPic1();">


Thanks. I tried both of these options and they worked except there is
some point at which both images rotate at the same time (which is what
we are trying to avoid). Do you know of a way to prevent this from
happening?

Yes, that was to be expected.

First you will have to define your wishes, then start programming.

Have both function call eachother after a defined delay:

=================

<script type='text/javascript'>
var midPicIndex = 0;
var bottomPicIndex = 0;
var middlepics = [...];
var bottompics = [...];


function midPic(){
if (midPicIndex >= middlepics.length) midPicIndex = 0;
d.images["pic1"].src="images/middle/"+middlepics[midPicIndex];
d.images["pic1"].alt=middlealts[midPicIndex++];

setTimeout("botPic()",1500);
};

function botPic(){
if (bottomPicIndex >= bottompics.length) bottomPicIndex = 0;
d.images["pic2"].src="images/bottom/"+bottompics[bottomPicIndex];
d.images["pic2"].alt=bottomalts[bottomPicIndex++];

setTimeout("midPic()",2500);
};
</script>

<body onload='setTimeout("midPic()",2500);'>
 
I

Isaac Schlueter

You shouldn't use setTimeout with a string argument. It's bad for the
same reason that eval is evil. Use a function object instead. (Since
you're basically just calling a function anyway, what's the point?)
Using a string argument means that you must make your functions
global, increasing the risk of collisions and reducing code
portability.

Also, nikki, you should be aware that the timeout value for setTimeout
and setInterval is a suggestion at best. It is ultimately up to the
browser how to interpret that request. setTimeout(myFunction,0) will
not execute myFunction right away--it'll happen asynchronously
whenever the browser decides that it has a free cycle.

More on the fun asynchronous things you can do with window.setTimeout:
http://isaacschlueter.com/tag/window.settimeout/


<html>
<body>
<img src=".." alt=".." id="toppic">
<img src=".." alt=".." id="botpic">

<script type='text/javascript'>
(function(){
var midPicIndex = 0;
var bottomPicIndex = 0;
var middlepics = [...];
var bottompics = [...];

var midPic = function (){
midPicIndex = (midPicIndex + 1) % middlepics.length;
d.images["pic1"].src="images/middle/"+middlepics[midPicIndex];
d.images["pic1"].alt=middlealts[midPicIndex];

setTimeout(botPic,1500);

};

var botPic = function (){
bottomPicIndex = (bottomPicIndex + 1) % bottompics.length;
d.images["pic2"].src="images/bottom/"+bottompics[bottomPicIndex];
d.images["pic2"].alt=bottomalts[bottomPicIndex];

setTimeout(midPic,2500);
};

window.setTimeout(topPic,1500);

})();
</script>
</body></html>

No globals, no need to wait for onload. Clean and neat.

--i
 
R

RobG

On Feb 14, 12:27 pm, "Isaac Schlueter" <[email protected]>
wrote:

Please include a trimmed quote of what you are replying to.
You shouldn't use setTimeout with a string argument. It's bad for the
same reason that eval is evil.

Why do you think that?
Use a function object instead. (Since
you're basically just calling a function anyway, what's the point?)
Using a string argument means that you must make your functions
global, increasing the risk of collisions and reducing code
portability.

You can also namespace variables to much the same effect.
Also, nikki, you should be aware that the timeout value for setTimeout
and setInterval is a suggestion at best.

And at worst?
It is ultimately up to the
browser how to interpret that request. setTimeout(myFunction,0) will
not execute myFunction right away--it'll happen asynchronously
whenever the browser decides that it has a free cycle.

More on the fun asynchronous things you can do with window.setTimeout:http://isaacschlueter.com/tag/window.settimeout/

"Well, here's the tricky part: setTimeout isn't just a sleep,
it's more like a fork and a sleep in one. That is, it makes
a function run asynchronously. It forks the browser's script
engine into another process, and runs the code side-by-side
with anything else that might be happening."

You seem to think that functions called by setTimeout run in a
separate thread, allowing the browser to remain function while they
run. That doesn't happen in any browser I tested, do you have an
example that does?

Also, setTimeout *is not* a sleep function and you shouldn't suggest
that it is. It tells the browser to run a function some time from
now, it doesn't halt or pause any process as might be expected of a
"sleep" function.

Further, it doesn't "fork" the script engine, the function will run as
soon after its designated time as it can, when no other script is
running. It certainly will not run "side-by-side" with other script
or window processes, a fact that can be easily demonstrated.
 
E

Evertjan.

Isaac Schlueter wrote on 14 feb 2007 in comp.lang.javascript:
You shouldn't use [..]

Who are you adderssing with "you"?

[please always quote on usenet, this is not email]
 
J

John Postlethwait

You shouldn't use setTimeout with a string argument. It's bad for the
same reason that eval is evil. Use a function object instead. (Since
you're basically just calling a function anyway, what's the point?)
Using a string argument means that you must make your functions
global, increasing the risk of collisions and reducing code
portability.

http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/setTimeout.asp

This is only true if you are ignoring browsers before IE5. I am not
sure what you want the scope of this script to be, but keep that in
mind when passing setTimeout function references instead of strings.
 
I

Isaac Schlueter

http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/set...

This is only true if you are ignoring browsers before IE5. I am not
sure what you want the scope of this script to be, but keep that in
mind when passing setTimeout function references instead of strings.

This is true. I in fact ignore all browsers before IE6.
http://developer.yahoo.com/yui/articles/gbs/gbs.html
http://developer.yahoo.com/yui/articles/gbs/gbs_browser-chart.html

Scripts should be unobtrusive and layer upon markup that is, in most
cases, otherwise functional.

--i
 
I

Isaac Schlueter

Isaac Schlueter wrote on 14 feb 2007 in comp.lang.javascript:
You shouldn't use [..]

Who are you adderssing with "you"?

[please always quote on usenet, this is not email]

Sorry for the confusion. I use the word "you" sometimes to imply "any
general person" or "one", not a particular person in this thread.
English lacks a good pronoun to mean "anyone", and many (American
speakers at least) often adopt this convention. "One" is used
sometimes (as in, "One shouldn't use ...") but it is a bit awkward,
IMO.

--i
 
E

Evertjan.

Isaac Schlueter wrote on 15 feb 2007 in comp.lang.javascript:
Isaac Schlueter wrote on 14 feb 2007 in comp.lang.javascript:
You shouldn't use [..]

Who are you adderssing with "you"?

[please always quote on usenet, this is not email]

Sorry for the confusion. I use the word "you" sometimes to imply "any
general person" or "one", not a particular person in this thread.
English lacks a good pronoun to mean "anyone", and many (American
speakers at least) often adopt this convention. "One" is used
sometimes (as in, "One shouldn't use ...") but it is a bit awkward,
IMO.

That was not what I ment, Isaac.
You [specific ;-)] replied to someone ore some earlier posting without
quoting. Without that quoting even the fact that you ment a general you
remained obscure.

That could be acceptable in a private email converstation,
but not on usenet.

Given the structure of usenet, you [general] can never be sure a previous
posting in a thread is yet or any more available on the users news
server, and if the users news reader supports threading pointers.

So usenet netiquette requires at least minimal quoting in a threaded
response.

That you [specific] posted via Google Groups does not make this
superfluous, since Google does not own this NG and most users seem to use
better, read easier in the original use sense of usenet, newsraders.
 
R

Richard Cornford

On Feb 15, 2:32 am, Isaac Schlueter wrote:
Scripts should be unobtrusive

Why should they be "unobtrusive"? Assuming you mean the same by that
as is meant when people speak of "unobtrusive javascript" (i.e.
absolute separation of mark-up and scripts).
and layer upon markup that is, in most
cases, otherwise functional.

True in general, but how errors are handled is quite important to
whether a semi-functional script will act to break otherwise
functional underlying mark-up. If you pass only function objects to -
setTimeout - (and do not provide those functions with fall-back -
toString - methods) then there will be no actual errors on browsers
that only accept strings as the first argument (in most such
browsers), but knowing that the related process has failed/will fail
will be difficult. And so ensuring clean degradation following the
failure may not be trivial.

Richard.
 
I

Isaac Schlueter

True in general, but how errors are handled is quite important to
whether a semi-functional script will act to break otherwise
functional underlying mark-up. If you pass only function objects to -
setTimeout - (and do not provide those functions with fall-back -
toString - methods) then there will be no actual errors on browsers
that only accept strings as the first argument (in most such
browsers), but knowing that the related process has failed/will fail
will be difficult. And so ensuring clean degradation following the
failure may not be trivial.

That's a good point in general, but it's not an all-or-nothing thing.
In this case, the browsers that do not accept a function object as the
first argument to setTimeout are very rare and outdated. Clean
degradation is a valid concern, of course, but there's a trade-off
here. setTimeout and setInterval perform better with a function
pointer, and this only causes a problem in browsers that are 3-4
versions out of date, and used by a vanishingly small minority of
users.

Modern CSS and semantic markup techniques in use across the net today
virtually ensure that ie4 users will have a very badly broken
experience anyway. We cannot save them, and it is often costly to
try. The best approach for these browsers, if a developer decides
that it's worth taking one at all, is to simply hide script and styles
(and other "enhancement" layers) from these browsers altogether.


Regarding degradation in the case of sending a function to setTimeout:
Unless I'm mistaken, the default toString() method of a function has
always been something like:
"function <name>() {
...
}"
Passed into setTimeout or setInterval, this will fail silently,
creating a function object and (if its unnamed) immediately garbage-
collecting it. I'm not sure that's such a bad fallback. IE4 users
get no switching image goodness, but they also don't get annoying
error messages.

It may be possible to change the Function.prototype.toString() to
support old browsers.
with({ts:null}){
ts=Function.prototype.toString;
Function.prototype.toString = function () {
return '('+ts.call(this)+')()';
}
}
However, I'm not sure if that would actually work in IE4, since I
usually just disregard browsers that old and so have no experience
with them.

--i
 
R

Richard Cornford

Isaac said:
That's a good point in general, but it's not an all-or-nothing
thing. In this case, the browsers that do not accept a function
object as the first argument to setTimeout are very rare and
outdated.

Are they? (beyond the observation that anything that is not IE 6 may be
called 'vary rare' by the numbers)
Clean degradation is a valid concern, of course, but there's
a trade-off here.

A trade-off? Knowing that there are no - setTimeout - implementations
that do not function with a string as the first argument you are
recommending a blanket adoption of the exclusive use of function
references and then saying that there is a trade-off around the
additional effort required to handle the consequential drop in
cross-browser compatibility that will follow?
setTimeout and setInterval perform better with a function
pointer,

Function reference. There is no concept of "pointer" in javascript.
and this only causes a problem in browsers that are 3-4
versions out of date, and used by a vanishingly small
minority of users.

3-4 versions? How are you counting "versions" here? Konqueror 2 did not
support function references are arguments to setTiemout, but its current
version is 3 (maybe 4 at a pinch). And the "small minority of users"
argument goes straight back to justifying IE 6 only websites.
Modern CSS and semantic markup techniques in use across the
net today virtually ensure that ie4 users will have a very
badly broken experience anyway.

But is that also true of NetFront 4 or IceBrowser 4?
We cannot save them, and it is often costly to try.

It is not more costly to provide clean degradation as a general fall-back
path than doing so only for script disabled IE 6.
The best approach for these browsers, if a developer
decides that it's worth taking one at all,

What made it the developer's decision? The developer is unlikely to be
developing a web based system for their own exclusive use, and whatever
purpose the system being developed has, and the (possibly business)
criteria of the end-client are much more relevant to overall design
decisions than the limitations of the developer.
is to simply hide script and styles (and other "enhancement"
layers) from these browsers altogether.

That implies an ability to identify web browsers, before you even get to
the question of how you would "hide" things from them.
Regarding degradation in the case of sending a function to
setTimeout: Unless I'm mistaken, the default toString() method
of a function has always been something like:
"function <name>() {
...
}"

More a massive over simplification than a mistake. Historically it has
not been possible to assume that the output of a function's toString
method would result in code that could be substituted for the original
function defining code and in that context result in the same function
object. The impression that this may be the case is only held by people
who haven't looked very extensively, or very hard.
Passed into setTimeout or setInterval, this will fail
silently,

Mostly yes, as I said above, but silent failure is not a rout to good
planed clean degradation in more than a very few cases. And with an
anonymous function the failure may not be silent.
creating a function object and (if its unnamed) immediately
garbage- collecting it.

That would depend on the way in which the string is interpreted. If it is
to be interpreted as a Program (as - eval - would) then the string
representation of an anonymous function (in the form "function( ... ){
.... }") would be a syntax as no Statement is allowed to commence with
"function" and the Identifier is not optional in a FunctionDeclaration.
I'm not sure that's such a bad fallback.

If that is what happens. A reported syntax error may be more disruptive.
IE4 users get no switching image goodness, but they also don't
get annoying error messages.

Why the fixation with IE 4? However, you were proposing using function
references with all uses of setTimeout, so loosing a bit of harmless
image swapping is not the extent of the consequences of failure here.
It may be possible to change the Function.prototype.toString() to
support old browsers.
with({ts:null}){
ts=Function.prototype.toString;
Function.prototype.toString = function () {
return '('+ts.call(this)+')()';

This relies on the function - toString - method returning a string that
can be turned into a functionally equivalent function object (which has
been observed not to be universally the case), that the function's have -
call - methods (which was introduced in ECMA 262, 3rd Ed. and so not too
good an idea in a back-compatibility fall-back path), and the function
used with setTimeout looses its identify (and so its scope chain) in the
process.

Custom - toString - methods are the means of providing fall-back for
setTimeout, but better alternatives, specifically assigned to the
functions used with setTimeout, have been proposed for the task.
}
}
However, I'm not sure if that would actually work in IE4,

IE 4 did not support the - call - method of functions. But why the
obsession with IE 4?
since I usually just disregard browsers that old and so
have no experience with them.

The more recent browsers that do not provide support for function
references as the first argument to setTimeout are probably more
significant.

Richard.
 

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,777
Messages
2,569,604
Members
45,227
Latest member
Daniella65

Latest Threads

Top