2011-08-27 26 views
1
<div id="image_cont"> 
    <img src="images/pic1.jpg" alt="pic1" /> 
    <img src="images/pic2.jpg" alt="pic2" /> 
    <img src="images/pic3.jpg" alt="pic3" /> 
</div> 

$(document).ready(function() { 
    slide(3, "image_cont", 5000, 600); 
}); 

function slide(numberOfImages, containerId, timeDelay, pixels) { 
    //start on first image 
    var i = 0; 
    var style = document.getElementById(containerId).style; 
    window.setInterval(function() { 
     if (i >= numberOfImages){ 
      i = 0; 
     } 
     var marginLeft = (-600 * i); 
     var pixelMovement = pixels/15; 


////////////////////////////////////////LOOK HERE////////////////////////////// 


     for (var j = 0; j * pixelMovement < 600; j++){ 
      window.setTimeout(function(){ 
//alert('marginLeft: ' + marginLeft + ' j: ' + j + ' pixelMovement: ' + pixelMovement); 
//this alert shows j is 15 when it should be 0, what's going on? 


/////////////////////////////////////////END////////////////////////////////// 
       style.marginLeft = (marginLeft - j * pixelMovement) + "px"; 
       }, 150); 
     } 
     i++; 
    }, timeDelay); 
} 
+0

可以添加页面的HTML吗? –

+0

它似乎为我工作得很好,但不能用'$('containerId')'替换'document.getElementById(containerId)'? – Ben

+0

只有名为'j'的变量< - 理解并理解问题:)这是关于SO的高度重复的问题,也是JavaScript中关闭的一个稍微混淆的方面。请记住,闭包绑定到自由变量(*不是值*),只有一个新的函数范围可以引入新的变量。 – 2011-08-27 09:12:31

回答

4

您不能在setTimeout函数中直接使用变量j,因为该函数在for循环完成后会运行一段时间,因此j有终止值,而不是调用setTimeout时的值。

可以捕获j的电流值的功能关闭,将在这样的setTimeout函数可用:

for (var j = 0; j * pixelMovement < 600; j++){ 
    window.setTimeout(function(cntr) { 
     return function() { 
      style.marginLeft = (marginLeft - cntr * pixelMovement) + "px"; 
     }; 
    } (j), 150); 
} 

我发现这种类型的封样的混乱的。我会试着解释发生了什么。我们传递给setTImeout()函数执行一个带有一个参数(我在这里命名为cntr)的匿名函数的结果,并将j的值作为该参数的值传递。当该函数执行时(它现在的值为j),该函数返回另一个匿名函数。这个其他匿名函数是在触发时实际调用的。但是,第二个匿名函数位于第一个函数的闭包内部,该函数的捕获值为j(作为一个变量,在函数闭包内部重命名为cntr以避免混淆解释)。这是匿名函数,使它很混乱,但它的工作原理。

+0

感谢您的教训,我想我主要理解它。不幸的是我的剧本仍然以意想不到的方式行事。我的魔力不够强大。 – deadghost

1

它应该是什么,因为window.setTimeout是一个“异步”功能,所以它执行后立即返回。

因此,在您的代码中,for循环保持循环,一段时间后(150ms)您的功能正在执行并且j变量的实际值被打印出来。

0

您创建并传递给setTimeout的函数都引用相同的循环计数器变量j - 循环运行完毕后,j将设置为导致循环终止的值。您需要使用闭包来确保您在内循环中创建的函数可以访问j的值函数定义的时间

看到这个答案的问题和解决方案的更多细节:

(傻变量名说清楚,这是有别于j):

window.setTimeout((function(jWhenFunctionWasDefined) { 
    return function() { 
    style.marginLeft = (marginLeft - jWhenFunctionWasDefined * pixelMovement) + "px"; 
    } 
})(j), 150) 
相关问题