PDA

View Full Version : Resolved setTimeout conflict.



jlizarraga
12-22-2008, 07:10 PM
EDIT: I meant "setInterval", not "setTimeout"!

Hi all,

I made a little slideshow script that works great, but when you have more than one on the page, their setTimeout bits apparently conflict because the timing of slide changes becomes erratic.

Each slideshow is constructed as a separate object, like so:



var oExample1 = new slideshow({
id: "exampleImage2",
speed: 3000,
user: true,
back: "backButton",
next: "nextButton",
pause: "pauseButton",
play: "playButton",
slides: [
{src: "images/yahoo.jpg", href: "http://www.yahoo.com", alt: "Yahoo! Search"},
{src: "images/shutterstock.jpg", href: "http://www.shutterstock.com", alt: "Shutterstock Images"},
{src: "images/google-news.jpg", href: "http://news.google.com/", alt: "Google News"}
]
});

oExample1.init();


Within that init() function is the following:



if(oObj.autoplay == true){
oObj.oSlideInterval = setInterval(oObj.nextSlide, oObj.speed);
}


Where oObj is a reference to oExample1.

I thought this would create a unique interval for that particular slideshow instance, but the intervals get very messed up when more than one slideshow is present. How can I create an interval that is unique to each slideshow?

Any help greatly appreciated.

Page:
http://www.autofusion.com/development/josh/demos/slidetest/
Javascript:
http://www.autofusion.com/development/josh/demos/slidetest/slideshow.js

jscheuer1
12-23-2008, 04:00 AM
There is some problem connecting to your live page and script at the moment. However, I can tell you that if oObj is in the global scope, it will be continually handed back and forth between all the slideshow objects on a page.

vwphillips
12-23-2008, 11:30 AM
may help


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>
<title></title>
<script language="JavaScript" type="text/javascript">
/*<![CDATA[*/
var oExample1 = new slideshow({
id: "Show0",
speed: 3000,
user: true,
back: "backButton",
next: "nextButton",
pause: "pauseButton",
play: "playButton",
slides: [
{src: "images/yahoo.jpg", href: "http://www.yahoo.com", alt: "Yahoo! Search"},
{src: "images/shutterstock.jpg", href: "http://www.shutterstock.com", alt: "Shutterstock Images"},
{src: "images/google-news.jpg", href: "http://news.google.com/", alt: "Google News"}
]
});

var oExample2 = new slideshow({
id: "Show1",
speed: 200,
user: true,
back: "backButton",
next: "nextButton",
pause: "pauseButton",
play: "playButton",
slides: [
{src: "images/yahoo.jpg", href: "http://www.yahoo.com", alt: "Yahoo! Search"},
{src: "images/shutterstock.jpg", href: "http://www.shutterstock.com", alt: "Shutterstock Images"},
{src: "images/google-news.jpg", href: "http://news.google.com/", alt: "Google News"}
]
});

function slideshow(obj){
this.obj=obj;
this.cnt=0;
}

slideshow.prototype.init=function(){
var oop=this;
setInterval(function(){ oop.cng(); },oop.obj['speed']);
}

slideshow.prototype.cng=function(){
this.cnt++;
document.Show[this.obj['id']].value=this.cnt;
}
/*]]>*/
</script></head>

<body>

<script> vic=0; </script>
<form name=Show id=Show style="position:absolute;visibility:visible;top:420px;left:0px;" >
<input size=100 name=Show0 >
<input size=10 name=Show1 >
<input size=10 name=Show2 >
<input size=10 name=Show3 >
<input size=10 name=Show4 >
<input size=10 name=Show5 >
<input size=10 name=Show6 >
<input size=10 name=Show7 >
<input size=10 name=Show8 >
<input size=10 name=Show9 ><br>
<textarea name=TA rows=1 cols=100 ></textarea>
</form>
<script language="JavaScript" type="text/javascript">
/*<![CDATA[*/
oExample1.init();
oExample2.init();

/*]]>*/
</script></body>

</html>

jscheuer1
12-23-2008, 05:13 PM
I was able to see the code and page now. Unfortunately, you have only one slideshow, so it doesn't adequately demonstrate the issue.

I missed this before, but that's an interval, not a timeout. It will continue firing unless cleared, whereas a timeout will only fire once, even if it isn't cleared. If you set another interval without clearing the first, the two will be firing off at various times, on and on and on.

That doesn't seem to be the issue (looks like you are appropriately clearing the interval), in fact - If you weren't - even a single slide show should have problems.

Just from experience with this sort of thing, I recall always setting up an array to hold the various instances of timeouts for later reference. Your code is more suited to using an Object for this purpose:


function slideshow(config){
if (!slideshow.timers)
slideshow.timers = {};
this.id = config["id"];
slideshow.timers[this.id] = null;
this.slides = config["slides"];
this.fade = (typeof(config["fade"]) != "undefined") ? config["fade"] : 0.5;
this.autoplay = (typeof(config["autoplay"]) != "undefined") ? config["autoplay"] : true;
this.speed = (typeof(config

Then later, wherever you need to refer to or create the interval for an instance of the slideshow, examples:


slideshow.timers[oObj.id] = setInterval(oObj.nextSlide, oObj.speed);


if(slideshow.timers[oObj.id])
clearInterval(slideshow.timers[oObj.id]);

jlizarraga
12-23-2008, 06:11 PM
Sweet, thanks guys.

Oh, and I did mean setInterval and not setTimeout from the beginning. Doh!

vwphillips
12-23-2008, 06:26 PM
just tested with


function initSlides(){

/* CONFIG */

// Configure each slideshow:
//
// NOTE: Slideshow configuration options:
//
// Option: Type: Description: Required / Default:
// ------- ----- ------------ -------------------
// id string ID of slide image. Required / (no default)
// slides array Array of slides. Required / (no default)
// fade number Fade speed in seconds. Optional / 0.5
// autoplay boolean Enable autoplay? Optional / true
// speed number Autoplay speed in milliseconds. Optional / 5000
// user boolean Enable user control? Optional / false
// back string ID of back button. Optional / (no default)
// next string ID of next button. Optional / (no default)
// pause string ID of pause button. Optional / (no default)
// play string ID of play button. Optional / (no default)
//
// NOTE: Individual slide configuration options:
//
// Option: Type: Description: Required / Default:
// ------- ----- ------------ -------------------
// src string SRC of the slide. Required / (no default)
// alt string ALT text of the slide. Optional / ""
// href string HREF of the slide. Optional / "#"
// exp string Expiration date of slide. Optional / (no default)
//
// NOTE: Format for expiration dates:
// exp: "2009.12.15" // Slide expires on December 15th, 2009

// Example 1: "speed" set to 3 seconds. All user controls enabled. "href" and "alt" set for each slide.
var oExample1 = new slideshow({
id: "exampleImage2",
speed: 3000,
user: true,
back: "backButton",
next: "nextButton",
pause: "pauseButton",
play: "playButton",
slides: [
{src: "http://www.autofusion.com/development/josh/demos/slidetest/images/yahoo.jpg", href: "http://www.yahoo.com", alt: "Yahoo! Search"},
{src: "http://www.autofusion.com/development/josh/demos/slidetest/images/shutterstock.jpg", href: "http://www.shutterstock.com", alt: "Shutterstock Images"},
{src: "http://www.autofusion.com/development/josh/demos/slidetest/images/google-news.jpg", href: "http://news.google.com/", alt: "Google News"}
]
});

// Initialize the slideshows:
oExample1.init();

var oExample3 = new slideshow({
id: "exampleImage3",
speed: 1000,
user: true,
back: "backButton3",
next: "nextButton3",
pause: "pauseButton3",
play: "playButton3",
slides: [
{src: "http://www.autofusion.com/development/josh/demos/slidetest/images/yahoo.jpg", href: "http://www.yahoo.com", alt: "Yahoo! Search"},
{src: "http://www.autofusion.com/development/josh/demos/slidetest/images/shutterstock.jpg", href: "http://www.shutterstock.com", alt: "Shutterstock Images"},
{src: "http://www.autofusion.com/development/josh/demos/slidetest/images/google-news.jpg", href: "http://news.google.com/", alt: "Google News"}
]
});

// Initialize the slideshows:
oExample3.init();
/* END CONFIG */

}


and the interval works fine with two slide shows as var oObj = this;

jlizarraga
12-23-2008, 09:20 PM
Do you mean you tested my existing code without changing it? (I haven't made any changes yet)

jlizarraga
12-23-2008, 09:32 PM
I implemented your timers object, John, and now everything works PERFECTLY.

Life saver as always!

jlizarraga
12-23-2008, 09:38 PM
The updated script can be found here:

http://www.autofusion.com/development/josh/demos/slideshow/

vwphillips
12-24-2008, 03:05 PM
there is no need to assign the setTimeout to the image object as in my previous post
var oObj=this;

and is unique to the application

the proof

http://www.vicsjavascripts.org.uk/Demos/081223.htm

jlizarraga
12-24-2008, 05:35 PM
That's what I thought, but if you look closely at your example you will see slides being skipped every so often.