Search code examples
javascriptsetintervalclearinterval

Providing multiple arguments to an anonymous function in setInterval


I'm not sure if this Javascript question has been asked before- I couldn't find it, but if I've missed it, my apologies.

I'm trying to create a page with checkboxes that will fade in/out a corresponding image. The fading will take 1 second, every 100ms, the opacity of the image increases or decreases by 0.1; when the opacity reaches 0 or 1, the setInterval call is stopped. However, I'm not sure how to pass arguments to an anonymous function call. I'm trying to pass two variables - the first is the ID of the image, obtained from the checkbox value, and the other is whether the tickbox is checked or not, so that the function knows whether to fade in or out.

However, I have run into a problem with the code as is (see below) and I think its due to the scope of the variables within the setInterval function call - thats why I'm asking about passing multiple arguments into the call.

for example:

<form action="">
<input type="checkbox" onclick='handleClick(this);' name="skymap" value="aurora">Aurora
<input type="checkbox" onclick='handleClick(this);' name="skymap" value="mainindex">Main Index
</form>

And the function is as follows (so far)

function handleClick(cb) 
{

var myInterval = setInterval(function () 
{
  if (cb.checked) // tick box checked - fade in.
  {
    document.getElementById( cb.value ).style.opacity+=0.1;  // I'll refactor all these style.opacity calls later on :)

    if( document.getElementById( cb.value ).style.opacity>1 ) // full opacity - stop the timer
    {
        document.getElementById( cb.value ).style.opacity = 1;
        clearInterval(myInterval);
    }
}
else // fade out
{
    document.getElementById( cb.val ).style.opacity-=0.1;

    if( document.getElementById( cb.val ).style.opacity<0 )
    {
        document.getElementById( cb.val ).style.opacity = 0;
        clearInterval(myInterval);
    }
}


}, 100);


}

The images are called things like:

<img id="aurora" src="aurora.png" />

Solution

  • You are running into a tricky problem there.

    First, you have written "cb.val" instead of "cb.value" in the else section

    Second, the opacity property of the object "cb" is of type string. The -= operation converts the opacity value into a number, as you cant do a minus operation on a string. The += operation instead, converts the number (0.1) into a string and adds to the end of the opacity string (e.g. if opacity is 0.1, the result will be "0.10.1"). As this value is invalid, it will be set to the last valid value and you are stuck in the loop

    Here is a working example:

    function handleClick(cb) 
    {
    
    var myInterval = setInterval(function () 
    {
      if (cb.checked) // tick box checked - fade in.
      {
        document.getElementById( cb.value ).style.opacity = parseFloat(document.getElementById( cb.value ).style.opacity) + 0.1  // I'll refactor all these style.opacity calls later on :)
    
        if( document.getElementById( cb.value ).style.opacity>1 ) // full opacity - stop the timer
        {
            document.getElementById( cb.value ).style.opacity = 1;
            clearInterval(myInterval);
        }
    }
    else // fade out
    {
        document.getElementById( cb.value ).style.opacity-=0.1;
    
        if( document.getElementById( cb.value ).style.opacity<0 )
        {
            document.getElementById( cb.value ).style.opacity = 0;
            clearInterval(myInterval);
        }
    }
    
    
    }, 100);
    
    
    }
    

    Another problem you could run into is, that the opacity property is not set by default (or at least you cant be sure). So the first time, opacity = "", empty string. This will cause jumps in your animation. Be sure to initialize the opacity if you detect an empty string.