Jump to content

Tell Me Why Window.settimeout() Is Not Working As Expected


stockton

Recommended Posts

In an attempt to build my own vertical scrolling display I have created the following function which works perfectly if I uncomment the alert() but fails to scroll vertically without that alert.

function ScrollNumbers(Current)    {    var xpos = findPosY(document.getElementById("Unit"));    if (xpos > 0) xpos *= -1;// alert("ScrollNumbers with "+" "+Current+" " + xpos);    var CurrentUnit  = parseInt(Current[Current.length - 2]);    var Hoogte = 0;    var a = 0;    var c = 0;    Hoogte = ((CurrentUnit)*94);  // CurrentUnit can be anything from 0 to 9    Hoogte *= -1;// alert("Entering loop Hoogte = "+ Hoogte+" "+xpos); -700 -302    if (Hoogte < xpos)	    {	    while (Hoogte < xpos)		    {		    xpos += -1;		    document.getElementById("Unit").style.top = xpos+"px";// alert("1st Hoogte = "+ Hoogte+" xpos = "+xpos);		    a=window.setTimeout("c += 1",200);//   	 doTimer();    		    }	    }    else	    {	    if (Hoogte > xpos)   // -302 -700		    {		    while (xpos > -999)			    {        xpos -= 1;			    document.getElementById("Unit").style.top = xpos+"px";// alert("2nd Hoogte = "+ Hoogte+" xpos = "+xpos);			    a=window.setTimeout("c += 1",200);//        doTimer();			    }		    xpos = 0;		    while (Hoogte < xpos)			    {        xpos -= 1;			    document.getElementById("Unit").style.top = xpos+"px";// alert("3rd Hoogte = "+ Hoogte+" xpos = "+xpos);			    a=window.setTimeout("c += 1",200);//        doTimer()			    }   	 }	    }    }

What I get is that the new display appears without any delay rather than scroll into position.The way I see it is that the image should scroll from where it is now(xpos) to the new position one px at a time with 200msec between.

Link to comment
Share on other sites

I'm quite sure it has to do with the way you're using setTimeout. When you execute the setTimeout in a loop, it will activate several timers, and all of them will finish after the same amount of time, while the rest of the code continues to execute. That means that the code leaves the loop and the code of the timers hasn't executed yet. If you put an alert() message after the loop, you'll notice that it appears before the setTimeout callbacks have been called.

Link to comment
Share on other sites

I hear what you are saying and what I am attempting is to smoothly scroll from the currently displayed number to the currently correct number and that is why the setTimeout.Sometimes the distance between the two numbers will be large . ie Let us say from 9 thru 0 to 8 and other times less so, let us say from 8 to 9.How would you suggest I achieve this?

Link to comment
Share on other sites

When you want to make something happen on certain intervals, use the setInterval function. A simple example:

/* Keep counting until you reach 10 */function count() {  if(this.num == 10) {	clearInterval(this.timer);  }  this.elem.innerHTML = this.num++;}// Properties are appended to the function so that they're easy to referencecount.num = 0;count.elem = document.getElementById("box");count.timer = setInterval(count, 500);

Link to comment
Share on other sites

  • 2 weeks later...

I have implemented the following code, hopefully correctly using your suggestion but I still get no scroll from the reel unless I uncomment the alert(). If I uncomment the alert() the code works exactly as expected.

			    A1 =  setInterval(SlideNumbers(Hoogte, xpos), 2000); function SlideNumbers(Proposed, Current)    {    if (Proposed > 0) Proposed *= -1;    if (Current > 0) Current  *= -1;    while (Proposed != Current)	    {	    Current -= 1;            if (Current < -999) Current = -1;// alert("Proposed = "+Proposed+" Current = "+Current);	    document.getElementById("Unit").style.top = Current+"px";	    }    clearInterval(A1);    }

Have a look at http://www.k9t.za.net/vicodo/index1.html for a better idea of what I mean by reel scrolling.

Link to comment
Share on other sites

When you're passing parameters to the function in setInterval or setTimeout you either need to use a function delegate or an anonymous function:

setInterval(function() {SlideNumbers(Hoogte, xpos)}, 2000)

The way you had it before, that line would execute the SlideNumbers function once, when you run setInterval, and then it would try to run the return value from SlideNumbers on the interval. But SlideNumbers doesn't return a function, so it wouldn't do anything. The way you have it set up now is that SlideNumbers only runs once. You clear the interval the first time you run the function, so it's only going to run it once. Your while loop is not going to show animation, it's going to loop through and update the top position as fast as it is able to. If you want it to animate smoothly then the procedure is to have the SlideNumbers function increment the top only one step at a time, and the interval should run the function on a schedule so that the top changes by one step every few milliseconds or so to provide a smooth animation.

Link to comment
Share on other sites

Duotone Fox please explain why the loop is a problem.The Old Man From Scene 24 if I implement your suggestion my script no longer works?
The problem with the loop was explained by justsomeguy in a previous post:
Your while loop is not going to show animation, it's going to loop through and update the top position as fast as it is able to. If you want it to animate smoothly then the procedure is to have the SlideNumbers function increment the top only one step at a time, and the interval should run the function on a schedule so that the top changes by one step every few milliseconds or so to provide a smooth animation.
Link to comment
Share on other sites

Duotone Fox please explain why the loop is a problem.The Old Man From Scene 24 if I implement your suggestion my script no longer works?
an interval executes on it's own timer. Once you start, it goes. And since an interval executes a function, that function that gets executed on each interval can do it's own validation, to determine whether a condition has been met that would need to clear the interval, or else update some relevant data associated with the intervals functionality. A loop and an interval will just cause problems, you shouldn't really need both for something like this.
Link to comment
Share on other sites

Sorry guys but now I have another issue.My code now looks like

    A1 = setInterval(function() {SlideNumbers(Previous, Current)}, 10);function SlideNumbers(PreviousOne, Next)    {    if (PreviousOne == Next)	    {	    clearInterval(A1);    }    UnitXpos -= 1;    PreviousOne += 1;    if (UnitXpos < -999) UnitXpos = 0;    document.getElementById("Debugger").innerHTML = "PreviousOne = " + PreviousOne + " Next = " + Next;    document.getElementById("Unit").style.top = UnitXpos+"px";    if (UnitXpos%10 == 0) ScrollTens();    }

and I find that the variable PreviousOne never increments.Both UnitXpos and PreviousOne are defined as global variables. Is this an issue?

Link to comment
Share on other sites

is that all your code? where are the definitions for Previous, Current, UnitXpos? Surely you can't do arithmetic with undefined variables. The compiler is not going to automatically assume you want them to treated as integers when adding/subtracting with them. Somewhere in your code you at the very minimum be defining these variables with some sort of starting value, i.e.

var Previous = //XXX some value;var Current = //XXX some value;var UnitXpos = //XXX some value;var A1 = setInterval(function() {SlideNumbers(Previous, Current)}, 10); function SlideNumbers(PreviousOne, Next){  if (PreviousOne == Next){	clearInterval(A1);  };  UnitXpos -= 1;  PreviousOne += 1;  if (UnitXpos < -999) UnitXpos = 0;   document.getElementById("Debugger").innerHTML = "PreviousOne = " + PreviousOne + " Next = " + Next;  document.getElementById("Unit").style.top = UnitXpos+"px";   if (UnitXpos%10 == 0) ScrollTens();};

edit: as Ingolme pointed out, you should be wanting to pass PreviousOne instead of Previous. Make sure your variable names are correct.

Link to comment
Share on other sites

Your setInterval function is passing the variable "Previous" and not "PreviousOne" so no value is being sent. I think a lot of changes still need to be made. Remember that the function is running in the global scope. The value of "Previous" never changes and you keep passing it to the function on each interval. Scroll up and look at my first example of setInterval. What I did was make some values as properties of the function so that they were easy to access. This also means that I don't need to pass any parameters to the function.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...