问题
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!
回答1:
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
回答2:
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.
来源:https://stackoverflow.com/questions/18115280/javascript-timeout-in-loop