1

I'm learning javascript for fun, and am having a weird problem. I'm trying to create my own fade-in function. However, my code doesn't work, it simply shows the "content" div in full opacity.

The setContentOpacity function does work, I've tested it by itself and it works like a charm.

Ideally what I think should be happening is that 1000 "setTimeout" calls should be placed on the "stack", with the first one setting opacity low with no timeout, the second one setting opacity a little higher with a small timeout, all the way to the last call which sets opacity to 1000 with 3000 timout.

So basically, it should be setting opacity to 0 right away, to ~333 in 1 second, to ~666 in 2 seconds, and to 1000 in 3 seconds. I think my logic is sound here; the calls to setting opacity should resolve in a manner over time that creates a fade in effect.

So here's the relevent code:

<script language='JavaScript' type='text/JavaScript'>

//takes a value from 0-1000
function setContentOpacity(value) {
   document.getElementById('content').style.opacity = value/1000;
   document.getElementById('content').style.filter = 'alpha(opacity=' + value/10 + ')';
}

function fadeInContent(){

setContentOpacity(0);

for (var i=0;i<=1000;i++)
{
   setTimeout(function(){setContentOpacity(i);}, (i*3));
}


}

onload=fadeInContent;

</script>

(note: I tried calling simply setTimeout(setContentOpacity(i), (i*3));, but it didn't seem to work, and I got slightly better results using the anonymous function)

Any idea what's wrong here? Thanks in advance!

2
  • You would do better finding a way for setContentOpacity to call the next timeout. Using the for-loop means you have 1000 timers running simultaneously. I don't know if that's bad, but it sounds scary. Commented Aug 7, 2013 at 23:16
  • "I don't know if that's bad, but it sounds scary." That's a good quote, I'm gonna remember that. Yeah, I'd thought of doing it somewhat recursively like that, I might just do that Commented Aug 7, 2013 at 23:18

2 Answers 2

2

You need to capture the value of i when assigning to setTimeout.

Try this

for (var i=0;i<=1000;i++)
{
   (function(ind) {
       setTimeout(function(){setContentOpacity(ind);}, (ind*3));

   })(i);
}

As you know the scope of a variable is function scoped. And the same value of i is shared by all the callbacks of setTimeout. So the value of i will be 1000 . So looks as if it had no effect, this is because the value of the variable scoped will always be the last iteration as it is shared by the same common scope. . By enclosing it in Immediately Invoked Function Expression you are creating a new function with the value of i scoped to it.

Check Fiddle

Sign up to request clarification or add additional context in comments.

3 Comments

why is this needed? what's the syntax mean? It looks like it's caused by somewhat strange scoping rules?
Thanks! Okay, that's really interesting. I would have thought that when setTimeout was added to the callstack then i would have been fixed at call-time. I guess setTimeout is called differently than I'm thinking.
setTimeout is one of the Asynchronous methods available in javascript.
0

I think the major issue here is that you're creating a 1000 setTimeout callbacks. An alternative, if you wanted to run something every x seconds would be setInterval.

var i = 0;
var refreshIntervalId = window.setInterval(function(){
    setContentOpacity( i * 3 );
    i++;

    if( i > 1000 ) {
        clearInterval( refreshIntervalId );
    }
}, 1000);

It will run once a second (1000ms), calling your opacity function each time until it hits a 1000, then turns off again.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.