Stumper for the Javascript gurus..take a swing

Bulldog13

Golden Member
Jul 18, 2002
1,655
1
81
Good afternoon,

I ve been working on this one for over a day, but no luck.

I am using the "Fading Scroller" from http://www.dynamicdrive.com/ .

The scroller works awesome for what I need it to do, but I was seeking to expand its functionality. The ultimate goal was to add a "pause" feature and a "next" feature, so that announcements could be iterated through. The follow is the unmodified code. Scroll down to bottom for specifics on my problem. Apparently attach code is borked so here it is. A better formatted version of the question can be found here.
http://www.webdeveloper.com/fo...howthread.php?t=167179

Any code is added I put in "-----------------------------------"






/* Custom code added by webmaster*/
var myimgobj = document.images["jsbutton"];
var mycontinue = new Boolean(true);
/* End custom code */


var delay = 7000; //set delay between message change (in miliseconds)
var maxsteps=30; // number of steps to take to change from start color to endcolor
var stepdelay=40; // time in miliseconds of a single step
//**Note: maxsteps*stepdelay will be total time in miliseconds of fading effect
var startcolor= new Array(255,255,255); // start color (red, green, blue)
var endcolor=new Array(0,0,0); // end color (red, green, blue)
var myctr = 0;
var fcontent=new Array();
begintag='<div style="font: normal 12px Verdana, Arial; padding: 3px;">'; //set opening tag, such as font declarations

fcontent[1]="Announcement 1";

fcontent[2]="Announcement 2";

fcontent[3]="Announcement 3";

fcontent[0]="Announcement 0";

closetag='</div>';

var fwidth='400px'; //set scroller width
var fheight='125px'; //set scroller height

var fadelinks=1; //should links inside scroller content also fade like text? 0 for no, 1 for yes.

///No need to edit below this line/////////////////


var ie4=document.all&&!document.getElementById;
var DOM2=document.getElementById;
var faderdelay=0;
var index=0;
var ctr =1;

/*Rafael Raposo edited function*/
//function to change content
function changecontent(){

----------------------------------
if (mycontinue==true){
----------------------------------
if (index>=fcontent.length)
index=0
if (DOM2){
document.getElementById("fscroller").style.color="rgb("+startcolor[0]+", "+startcolor[1]+", "+startcolor[2]+")"
document.getElementById("fscroller").innerHTML=begintag+fcontent[index]+closetag
if (fadelinks)
linkcolorchange(1);
colorfade(1, 15);
}
else if (ie4)
document.all.fscroller.innerHTML=begintag+fcontent[index]+closetag;
index++
}
}
// colorfade() partially by Marcio Galli for Netscape Communications. ////////////
// Modified by Dynamicdrive.com

function linkcolorchange(step){
var obj=document.getElementById("fscroller").getElementsByTagName("A");
if (obj.length>0){
for (i=0;i<obj.length;i++)
obj.style.color=getstepcolor(step);
}
}

/*Rafael Raposo edited function*/
var fadecounter;
function colorfade(step) {
if(step<=maxsteps) {
document.getElementById("fscroller").style.color=getstepcolor(step);
if (fadelinks)
linkcolorchange(step);
step++;
fadecounter=setTimeout("colorfade("+step+")",stepdelay);

}else{
clearTimeout(fadecounter);
document.getElementById("fscroller").style.color="rgb("+endcolor[0]+", "+endcolor[1]+", "+endcolor[2]+")";
setTimeout("changecontent()", delay);

}
}

/*Rafael Raposo's new function*/
function getstepcolor(step) {
var diff
var newcolor=new Array(3);
for(var i=0;i<3;i++) {
diff = (startcolor-endcolor);
if(diff > 0) {
newcolor = startcolor-(Math.round((diff/maxsteps))*step);
} else {
newcolor = startcolor+(Math.round((Math.abs(diff)/maxsteps))*step);
}
}
return ("rgb(" + newcolor[0] + ", " + newcolor[1] + ", " + newcolor[2] + ")");
}

if (ie4||DOM2)
document.write('<div id="fscroller" style="border:2px solid #CC0000; text-align:left; width:100%;height:'+fheight+'"></div>');

if (window.addEventListener)
window.addEventListener("load", changecontent, false)
else if (window.attachEvent)
window.attachEvent("onload", changecontent)
else if (document.getElementById)
window.onload=changecontent

----------------------------------
function handleMDown()
{
if (mycontinue==true)
{

mycontinue = false;
document.images["jsbutton"].src="images/start.gif";

}

else
{
document.images["jsbutton"].src="images/stop.gif";
mycontinue = true;
changecontent();

}

return true;
}
----------------------------------

</script>

----------------------------------
<a href="#" onMouseDown="return handleMDown()"><img name="jsbutton" src="images\stop.gif"></a>
----------------------------------

As you can see I put in a start / stop button that calls a handleMDown() function. The pause functionality works, by setting my mycontinue variable to false, it successfully stops rotating. When the button is clicked again, and it is reset to true, changecontent() is called and it starts rotating again, but...the delay between message rotations gets wacky and it starts rotating too quickly. This problem is magnified if you press the button 4 or 5 times. I believe this is b/c there is already the first changecontent() running when the site loads, then every time the "start" button is pressed to restart the scroller after being paused, it recalls changecontent() causing the code to change the announcement to run too quickly.

I tried removing the function call to changecontent() on the start click, but it will not start rotating the announcements again. It just stays paused.

I have already spent awhile on the issue so any help is greatly appreciated !
 

CTho9305

Elite Member
Jul 26, 2000
9,214
1
81
edit: Never mind. I misinterpreted the bug and don't feel like reading all that code.

FYI, setInterval / clearInterval are better than setTimeout / clearTimeout if you're going to fire something repeatedly.
 

PhatoseAlpha

Platinum Member
Apr 10, 2005
2,131
21
81
Eh, from the basic look of it, you might be able to remove the call to changecontent in handleMDown, and have changecontent set a timeout to recall itself after the delay if mycontinue == false.



I'll also bet you that if you stop it, wait 9 seconds, then press start, it works just fine. I'd wager whats going on is the timeout in fadecounter is still elapsing. You stop it, but until 7 seconds pass by, changecontent isn't invoked, and thus isn't aborted by the check. You press start, and it goes and starts another timer, but then the first one hits, and since you've changed you flag back to true, it goes on like it never stopped, and does it's job continuously...however, the changecontent called in your button press routine is also doing the same job, so you see it speed up.....

It's a hack, that's for sure. It won't cause it to pick back up changing immediately either - it will wait for the timeout to expire, which could be up to 7 seconds from when you press the button. And because changecontent set's timeouts, you won't be able to just call it in your Next function, if that's what you're planning, or you'd get the exact same behavior.


You're gonna end up with a really, really ugly kludge of a piece of code this way though. I'd probably just preserve as much of the code to actually do the fades and whatnot as possible, and rewrite the timing controls entirely.