Solved

setTimeout problem!

Posted on 2004-04-14
15
2,306 Views
Last Modified: 2008-02-01
Greetings experts!

I have a weird problem using the settimeout function.

First off, the settimeout:

   setTimeout("func();",x);

 function waits x milisenconds before calling func() right?

If that statment is correct i can't understand what i'm doing wrong with the following script.

This script has a function  change(r,g,b, rT, gT, bT, where);

The first 3 params are the red, green and blue components of a color, let's imagine,  the bgColor of a "td" in a "table". The rT, gT, and bT are the rgb colors that i'm trying to make. The "where" param is just the id of the "td".

I would like to make a soft transistion between color rgb and color rTgTbT. (Hope you understand my idea)
When the user puts the mouse over the "td", it would softly change between lightblue to blue for example.

So the problem is that the setTimeout function simply doens't wait the miliseconds that i'm requesting... Don't know why really.

First i tried this:

NOTE: I'm only changing the blue color.

//*********************************************************
function  change(r,g,b, rT, gT, bT, where){
      varr res="#";
      if(r>rT){
           while(r!=rT){
            var res="#";
            --r;
            res+=r;
            res+=g;
            res+=b;
            where.style.backgroundColor=res;
            setTimeout("change("+r+","+g+","+b+","+rT+","+gT+","+bT+","+where+")",1000);
           }
      }
 }
//*********************************************************

So at the last line of code the setTimeout it's suposed to wait 1000 milisenconds before calling the change function with the new values.

Since It doens't work i tried to make a Wait function that would wait 1000 milisenconds and then simply return.

//*********************************************************
var tau=1;
      function wait(){// Wait 1 second before returning to the while loop inside function Change
                  --tau;
                  if(tau==0){
                        tau=1;
                        return;
                  }
                  window.setTimeout("wait();",1000);// Why it doesn´t wait 1 second??
      }
//*********************************************************

So the Change function would look like:

//*********************************************************
function  change(r,g,b, rT, gT, bT, where){
      varr res="#";
      if(r>rT){
           while(r!=rT){
            var res="#";
            --r;
            res+=r;
            res+=g;
            res+=b;
            where.style.backgroundColor=res;
            wait();
           }
      }
 }
//*********************************************************

And again it doens't work and i don´t know why...

I believe tha is a really simple error in this but i can't see where it is...

Hope you can help me!

Thank you.

P.S: Here is a sample .html file for you to test with the above functions:

/////*********************
test.html
////**********************

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
      <head>
            <title></title>
            <meta name="GENERATOR" content="Microsoft Visual Studio .NET 7.1">
            <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
            <script>
            var td1;
            
            var tau=1; // var for the function wait()

            function onLoad(){
                  td1 = document.getElementById("TD1");
            }
            function  change(r,g,b, rT, gT, bT, where){
                                                
                  var res="#";
                  if(r>rT){
                        while(r!=rT){
                              var res="#";
                              --r;
                              res+=r;
                              res+=g;
                              res+=b;
                              where.style.backgroundColor=res;
                              //setTimeout("change("+r+","+g+","+b+","+rT+","+gT+","+bT+","+where+")",1000);
                              wait();
                        }
                  }

            }
            
            function wait(){// Wait 1 second before returning to the while loop inside function Change
                  --tau;
                  if(tau==0){
                        tau=1;
                        return;
                  }
                  window.setTimeout("wait();",1000);// Why it doesn´t wait 1 second??
            }
            function overBotao(id){
                  switch(id){
                        case '1':
                              change("87","ce","fa","41","69","e1",td1);                        
                              td1.style.color="white";
                        break;
                  }
            }
            </script>
      </head>
      <body onload="onLoad();">
            <TABLE id="Table1" cellSpacing="1" cellPadding="1" width="300" border="1">
                  <TR>
                        <TD id="TD1" onmouseover="overBotao('1');" bgColor="skyblue">
                              Test
                        </TD>
                  </TR>
            </TABLE>
      </body>
</html>

////**************
End of Test.html
////**************

0
Comment
Question by:MeiaDose
  • 7
  • 3
  • 3
  • +2
15 Comments
 
LVL 33

Expert Comment

by:knightEknight
Comment Utility
to start, change this:
   varr res="#";

to this:
   var res="#";
0
 
LVL 2

Author Comment

by:MeiaDose
Comment Utility
:)

A copy paste error :)

Thanks.
0
 
LVL 5

Expert Comment

by:alambres
Comment Utility
Hey!
since you're calling recursively the change function I suggest you to use setInterval instead of setTimeout.
setInterval("func();",x)  calls the specified function every x miliseconds.
to stop the loop use clearInterval, that's:

// start the loop like this:
var tid = setInterval("func();",x);

// stop it like this:
clearInterval(tid);


 
0
 
LVL 2

Author Comment

by:MeiaDose
Comment Utility
I've changed to this:

            function  change(r,g,b, rT, gT, bT, where){
                                                
                  var res="#";
                  if(r>rT){
                        while(r!=rT){
                              var res="#";
                              --r;
                              res+=r;
                              res+=g;
                              res+=b;
                              where.style.backgroundColor=res;
                              var timer=setInterval("change("+r+","+g+","+b+","+rT+","+gT+","+bT+","+where+")",1000);
                        }
                        clearInterval(timer);
                  }

            }

If you try this on the test.html you will see that the color of the "td" goes right to the target color (softer blue) and after 1 second(?) appears an error saying that "ce" is undefined and continues to appear the error box for 30 times (?).
0
 
LVL 6

Expert Comment

by:James Looney
Comment Utility
Also, for kicks, try changing the double quotes to single quotes - looks like the double quotes may be matching funny.  So take your original code:

function  change(r,g,b, rT, gT, bT, where){
     varr res="#";
     if(r>rT){
          while(r!=rT){
          var res="#";
          --r;
          res+=r;
          res+=g;
          res+=b;
          where.style.backgroundColor=res;
          setTimeout("change("+r+","+g+","+b+","+rT+","+gT+","+bT+","+where+")",1000);
          }
     }
 }


And change to this:

function  change(r,g,b, rT, gT, bT, where){
     varr res="#";
     if(r>rT){
          while(r!=rT){
          var res="#";
          --r;
          res+=r;
          res+=g;
          res+=b;
          where.style.backgroundColor=res;
          setTimeout("change('+r+','+g+','+b+','+rT+','+gT+','+bT+','+where+')",1000);
          }
     }
 }



I am on a Mac and this works in Safari and Mozilla
0
 
LVL 2

Author Comment

by:MeiaDose
Comment Utility
It changes the color alright but the point is that i wanted each time we decrement the red param and ence produce the color:

          --r;
          res+=r;
          res+=g;
          res+=b;

it should wait 1 second

          setTimeout("change('+r+','+g+','+b+','+rT+','+gT+','+bT+','+where+')",1000);

And it doens't wait 1 second each time it decrements the red param.

Actualy if you put:

           setTimeout("change('+r+','+g+','+b+','+rT+','+gT+','+bT+','+where+')",100000000);

It doens't change the time that we have to wait to get to the final color.

I'm on IE 6.0.2800 Windows Xp Home Edition
0
 
LVL 2

Author Comment

by:MeiaDose
Comment Utility
Btw,

I've tried with the setInterval and changed the double quotes to single quotes and it doesn´t work too.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 2

Author Comment

by:MeiaDose
Comment Utility
So you can see what i'm trying to do copy this code:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
      function  change(r,g,b, rT, gT, bT, where){
            var res="#";
            if(r>rT){
                  while(r!=rT){
                        var res="#";
                        --r;
                        res+=r;
                        res+=g;
                        res+=b;
                        where.style.backgroundColor=res;
                        alert("A ENTRAR NO WAIT");
                        wait();
                        alert("A SAIR DO WAIT");
                  }
            }

      }

var tau =1;
      function wait(){
            --tau;
            if(tau==0){
                  tau=1;
                  return;
            }
            window.setTimeout("wait();",1000);
      }
////////////////////////////////////////////////////////////////////////////////////////////////////////////      
Just press the Enter button without stopping please :)

0
 
LVL 4

Expert Comment

by:monolith_888
Comment Utility
MeiaDose, I had some fun with this one!

Here's it for you top to bottom.  We set some global variables at the top which contains your colors, and that is also the spot where we change them.  There's a bunch of cool stuff here, but I tidied up the code (I hope that was ok).

Give it a whirl and let me know what you think!

-monolith
========================

<html>
<head><title></title>
<script>
var theTD;
var res;
var theTimer;

var colors =
  {
  r  : 87,
  g  : 'ce',
  b  : 'fa',
  rT : 41,
  gT : 69,
  bT : 'e1'
  };

function change()
  {
  if(colors.r > colors.rT)
    {
    --colors.r;
    res="#";
    res+=colors.r;
    res+=colors.g;
    res+=colors.b;

    theTD.style.backgroundColor=res;

    theTimer = window.setTimeout("change()",100);
    }
  else
    {
    window.clearTimeout(theTimer);
    alert('all done!')
    }
}

function overBotao(num)
  {
  switch(num)
    {
    case '1':
    change();
    theTD.style.color="white";
    break;
  }
}

function onLoad() { theTD = document.getElementById("TD1"); }
</script>
</head>
<body onLoad="onLoad();">
<TABLE id="Table1" cellSpacing="1" cellPadding="1" width="300" border="1">
<TR><TD id="TD1" onmouseover="overBotao('1');" bgColor="skyblue">Test</TD></TR>
</TABLE>
</body>
</html>
0
 
LVL 4

Expert Comment

by:monolith_888
Comment Utility
Changed the code a bit so you could set custom colors for each TD you wanted to mouseover by adding a setcolors() function (including a parameter for the text color), which in turn fires off the change() function.
I also made it so that mulitple mouseovers won't affect the timer by adding a flag telling us the timer is running.
Here's the new <script> -- </script>

-monolith

<script>
var theTD;
var res;
var theTimer;
var timerRunning = false;

var colors =
  {
  r  : 0,
  g  : 0,
  b  : 0,
  rT : 0,
  gT : 0,
  bT : 0,
  tx : 0
  };

function change()
  {
  if(colors.r > colors.rT)
    {
    --colors.r;
    res="#";
    res+=colors.r;
    res+=colors.g;
    res+=colors.b;

    theTD.style.backgroundColor=res;

    theTimer = window.setTimeout("change()",100);
    timerRunning = true;
    }
  else
    {
    window.clearTimeout(theTimer);
    timerRunning = false;
    alert('all done!')
    }
}

function setColors(r,g,b,rT,rG,rB,tx)
  {
  colors.r  = r;
  colors.g  = g;
  colors.b  = b;
  colors.rT = rT;
  colors.rG = rG;
  colors.rB = rB;
  colors.tx = tx
  change();      
  }

function overBotao(num)
  {
  if(timerRunning)
        return;

  switch(num)
    {
    case '1':
      setColors(87,"ce","fa",41,69,"e1","white");
    theTD.style.color=colors.tx;
    break;
  }
}

function onLoad() { theTD = document.getElementById("TD1"); }
</script>
0
 
LVL 2

Author Comment

by:MeiaDose
Comment Utility
Thank you very much monolith_888!

However it still has minor bugs:

For example, if we do:

setColors(99,"ce","fa",41,69,00,"white");

It will go from 99 to 00. But when it reaches the number 9 it gives an error because it isnt a valid number for the color. It should be 09, 08, 07.

if you do:

setColors("ff","ce","fa",41,69,00,"white");

It should go from ff to 00, but when the script does:

 if(colors.r > colors.rT)

It doesn't understand that ff is > that 0.

How can we say that a certain number is hexadecimal?

Thank you once again for your help!
0
 
LVL 4

Assisted Solution

by:monolith_888
monolith_888 earned 85 total points
Comment Utility
Ok, here's a much improved version.  I have never worked so hard on a question!  Use this for now, I need to go to bed now, but might play with again tomorrow morning.  Hope you like it!

-monolith_888

<script> to </script> again:

=============================
<script>
var theTD;
var res;
var theTimer;
var timerRunning = false;

var colors =
  {
  r  : 0,
  g  : 0,
  b  : 0,
  rT : 0,
  gT : 0,
  bT : 0,
  tx : 0
  };

function change()
  {
  if(colors.r > colors.rT)
    {
    convertColorR();

    res="#";
    res+=colors.r;
    res+=colors.g;
    res+=colors.b;

    theTD.style.backgroundColor=res;

    theTimer = window.setTimeout("change()",100);
    timerRunning = true;
    }
  else
    {
    window.clearTimeout(theTimer);
    timerRunning = false;
    alert('all done!')
    }
}

function convertColorR()
  {
  if(colors.r == 10) colors.r = "09";

  colors.r = parseInt(colors.r,16);
  --colors.r;

  if(colors.r <= 9)
    {
    var tempNum = colors.r+"";
    colors.r = tempNum.length < 2 ? "0"+colors.r : colors.r;
    }

  colors.r = colors.r.toString(16);
  }

function setColors(r,g,b,rT,rG,rB,tx)
  {
  colors.r  = r;
  colors.g  = g;
  colors.b  = b;
  colors.rT = rT;
  colors.rG = rG;
  colors.rB = rB;
  colors.tx = tx
  change();    
  }

function overBotao(num)
  {
  if(timerRunning)
    return;

  switch(num)
    {
    case '1':
    setColors("ff","ce","fa","41","69","e1","white");
    theTD.style.color=colors.tx;
    break;
  }
}

function onLoad() { theTD = document.getElementById("TD1"); }
</script>
0
 
LVL 5

Accepted Solution

by:
alambres earned 85 total points
Comment Utility
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
     <head>
          <title></title>
          <script type="text/javascript">
               
                  function colour (hex)
                  {
                        this.r = HexToDec(hex.substr(1,2));
                        this.g = HexToDec(hex.substr(3,2));
                        this.b = HexToDec(hex.substr(5,2));
                        this.toHex = tH;
                        
                        function tH ()
                        {
                              return '#' + DecToHex(this.r) + DecToHex(this.g) + DecToHex(this.b);      
                        }
                  }
            
                  function DecToHex(dec) {return dec.toString(16);}
                  function HexToDec(hex) {return parseInt(hex,16);}
                  
         
                  function degrade (obj)
                  {
                        obj.setAttribute("tid", setInterval ("adjustColor('"+obj.id+"');",30));
                  }
             
                  function adjustColor(whereToId)
                  {
                        var obj = document.getElementById(whereToId);
                        col0 = obj.getAttribute("iCol");
                        col1 = obj.getAttribute("fCol");
                        
                        if (col0.toHex() != col1.toHex())
                        {
                              if (col0.r < col1.r) col0.r++; else if (col0.r > col1.r) col0.r--;
                              if (col0.g < col1.g) col0.g++; else if (col0.g > col1.g) col0.g--;
                              if (col0.b < col1.b) col0.b++; else if (col0.b > col1.b) col0.b--;
                              obj.style.backgroundColor = col0.toHex();      
                        }
                        else {alert ('listo!');clearInterval(obj.getAttribute("tid"));}
                                    
                  }
            
          function overBotao(fadeType, obj){
               switch(fadeType){
                    case '1':
                                    obj.setAttribute("iCol",new colour("#87cefa"));
                                    obj.setAttribute("fCol",new colour("#4169e1"));
                        degrade(obj);
                        obj.style.color="white";
                    break;
               }
          }
         
          </script>
     </head>
     <body>
          <TABLE id="Table1" cellSpacing="1" cellPadding="1" width="300" border="1">
               <TR>
                    <TD id="TD1" onmouseover="overBotao('1', this);" bgColor="skyblue">
                        <b>Test</b>
                    </TD>
               </TR>
          </TABLE>
         
     </body>
</html>
0
 
LVL 2

Author Comment

by:MeiaDose
Comment Utility
Thank you everybody for your help!

Especial thanks goes to monolith and alambres! :)

Monolith's script is more optimized than alambres, but in the end both do what i wanted to.

I will slip the points between Alambres and monolith and i increased the points from 125 to 170!

Thank you once again!

By the way here's the final version of the test.html page

++++++++++++++++++++++++++++++++++++

<html>
     <head>
          <title></title>
          <script type="text/javascript">
         
          function piu(){alert("piu");}
         
                  var finish=0;
                  var process = new Array(5);
               function colour (hex)
               {
                    this.r = HexToDec(hex.substr(1,2));
                    this.g = HexToDec(hex.substr(3,2));
                    this.b = HexToDec(hex.substr(5,2));
                    this.toHex = tH;
                   
                    function tH ()
                    {
                         return '#' + DecToHex(this.r) + DecToHex(this.g) + DecToHex(this.b);    
                    }
               }
         
               function DecToHex(dec) {return dec.toString(16);}
               function HexToDec(hex) {return parseInt(hex,16);}
               
         
               function degrade (obj)
               {
                              obj.setAttribute("tid", setInterval ("adjustColor('"+obj.id+"');",30));
               }
           
               function adjustColor(whereToId)
               {      
                              
                    var obj = document.getElementById(whereToId);
                    col0 = obj.getAttribute("iCol");
                    col1 = obj.getAttribute("fCol");
                   
                    if (col0.toHex() != col1.toHex())
                    {
                         if (col0.r < col1.r) col0.r++; else if (col0.r > col1.r) col0.r--;
                         if (col0.g < col1.g) col0.g++; else if (col0.g > col1.g) col0.g--;
                         if (col0.b < col1.b) col0.b++; else if (col0.b > col1.b) col0.b--;
                         obj.style.backgroundColor = col0.toHex();    
                    }
                    else {
                                    //alert ('listo!');
                                    clearInterval(obj.getAttribute("tid"));
                                    
                              }
                             
               }
         
          function overBotao(fadeType, obj){
               switch(fadeType){
                    default:
                                          obj.style.color="white";                                          
                                          obj.setAttribute("iCol",new colour("#87cefa"));
                                          obj.setAttribute("fCol",new colour("#4169e1"));
                                          degrade(obj);                                          
                                          break;
               }
          }
         
          function outBotao(fadeType, obj){
               switch(fadeType){
                    default:
                                          obj.setAttribute("iCol",new colour("#4169e1"));
                                          obj.setAttribute("fCol",new colour("#87cefa"));
                                          degrade(obj);
                                          obj.style.color="black";
                                          break;
               }
          }
          </script>
     </head>
     <body>
          <TABLE id="Table1" cellSpacing="1" cellPadding="1" width="300" border="1">
               <TR>
                    <TD id="TD1" onmouseout="outBotao('1', this);" onmouseover="overBotao('1', this);" bgColor="skyblue">
                        <b>Thank you Experts Exchange!</b>
                    </TD>
               </tr>
               <tr>
                    <TD id="TD2" onmouseout="outBotao('2', this);" onmouseover="overBotao('2', this);" bgColor="skyblue">
                        <b>Thank you Monolith!</b>
                    </TD>
               </tr>
               <tr>
                    <TD id="TD3" onmouseout="outBotao('3', this);" onmouseover="overBotao('3', this);" bgColor="skyblue">
                        <b>Thank you Alambres!</b>
                    </TD>
               </tr>
               <tr>
                    <TD id="TD4" onmouseout="outBotao('4', this);" onmouseover="overBotao('4', this);" bgColor="skyblue">
                        <b>Thank you!</b>
                    </TD>
               </TR>
          </TABLE>
         
     </body>
</html>

++++++++++++++++++++++++++++++++++

0
 
LVL 5

Expert Comment

by:alambres
Comment Utility
You're welcome!  glad to help ya

peace

alambres
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Avoid defining the variables in the global scope; trying to define them in a local function scope. Because:   • Look-up is performed every time a variable is accessed.   • Variables are resolved backwards from most specific to least specific scope…
In this article, we'll look how to sort an Array in JavaScript, including the more advanced techniques of sorting a collection of records either ascending or descending on two or more fields. Basic Sorting of Arrays First, let's look at the …
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

728 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now