Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/384.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用setTimeout函数&;随机函数。设置类元素动画的步骤_Javascript_Jquery_Arrays_Jquery Animate_Settimeout - Fatal编程技术网

Javascript 使用setTimeout函数&;随机函数。设置类元素动画的步骤

Javascript 使用setTimeout函数&;随机函数。设置类元素动画的步骤,javascript,jquery,arrays,jquery-animate,settimeout,Javascript,Jquery,Arrays,Jquery Animate,Settimeout,我的调试技能并不能帮助我找出我在这里做错了什么 我希望数组中的每个元素在指定时间后使用setTimeout函数设置动画 我没有收到任何错误,循环似乎运行得很好,但是,数组中的元素最终都不会从原来的位置移动到新的位置 function publicity() { // placing elements with class name 'cCameras' inside an array var eCamerasArray = $(".cCameras").toArray(); // creatin

我的调试技能并不能帮助我找出我在这里做错了什么

我希望数组中的每个元素在指定时间后使用setTimeout函数设置动画

我没有收到任何错误,循环似乎运行得很好,但是,数组中的元素最终都不会从原来的位置移动到新的位置

function publicity()
{
// placing elements with class name 'cCameras' inside an array
var eCamerasArray = $(".cCameras").toArray();
// creating 2 arrays to hold left & top values of each element
var iLeftPosArray = [];
var iTopPosArray = [];
// loop to run through each element in array
for( var i = 0; i < eCamerasArray.length; i++)
{
    // timer variable set for each element to be used in setTimeout func.
    var timer = Math.floor (Math.random()*300) + 100;
    // setTimeout func. used to animate each element after a specified (timer) time
    window.setTimeout (function ()
    {
        iLeftPosArray[i] = Math.floor (Math.random() *139) + 360;
        iTopPosArray[i] = Math.floor (Math.random() *160) + 100 ;
        $(eCamerasArray[i]).animate ({left: iLeftPosArray[i] + "px", top: iTopPosArray[i] + "px"}, 100, "linear");
        return [iLeftPosArray[i], iTopPosArray[i]];
    }, timer);
}
}
功能宣传()
{
//将类名为“cCameras”的元素放置在数组中
var eCamerasArray=$(“.cCameras”).toArray();
//创建2个数组以保存每个元素的左值和顶值
var iLeftPosArray=[];
变量数组=[];
//循环以遍历数组中的每个元素
对于(变量i=0;i
您可以通过创建闭包来修复它:

(function publicity() {
    var eCamerasArray = $(".cCameras"),
        iLeftPosArray = [],
        iTopPosArray = [],
        timer;
    for(var i = 0; i < eCamerasArray.length; i += 1) {
        timer = Math.floor (Math.random() * 300) + 100;
        (function (i) {
            window.setTimeout (function () {
                iLeftPosArray[i] = Math.floor (Math.random() * 139) + 360;
                iTopPosArray[i] = Math.floor (Math.random() * 160) + 100 ;
                $(eCamerasArray[i]).animate ({left: iLeftPosArray[i] + "px", top: iTopPosArray[i] + "px"}, 300, "linear");
                return [iLeftPosArray[i], iTopPosArray[i]];
            }, timer);
        }(i));
    }
}());
(功能宣传(){
变量eCamerasArray=$(“.cCameras”),
iLeftPosArray=[],
ITO阵列=[],
定时器;
对于(变量i=0;i
您可以在此处看到效果:


致以最良好的祝愿

展开一个简单的循环,您可以看到发生了什么:

var i = 0;

window.setTimeout( function(){
      //No local i so it must be outside
    console.log(i);

}, 1000 );

i++;

window.setTimeout( function(){
     //No local i so it must be outside
    console.log(i);

}, 1000 );

i++;

window.setTimeout( function(){
      //No local i so it must be outside
    console.log(i);

}, 1000 );
如您所见,所有函数都引用相同的
i
,因此 一旦定时器触发,它们都将记录
2
。没有一个 拥有本地
i

您可以像这样创建“本地”
i

(function(i){
|---------^  //i found here, no need to use the global i
|   window.setTimeout( function(){
-------------------- //no local i here so it must be outside
        console.log(i);

    }, 1000 );  


})(i) //pass the "global" i as argument, with the value it has right now

javascript没有块级作用域,因此所有函数都将引用相同的
i
。。有人在这上面找到了一个副本:p@Esailija,你完全失去了我,请你详细说明。@Esailija-他在数组中使用它,我认为他不会有这个代码的问题。Kayote,通过确认
eCamerasArray
的值开始调试,然后在循环后确认
iLeftPosArray
IToposArray
的结果值。@KevinB?循环立即执行,
i
将是超时开始触发后创建的所有函数的相同值。关于这个问题,每天至少有10个问题。Firebug实际上在函数中运行得相当奇怪,但它确实贯穿了整个过程,包括通过console.log输出正确的内容。iLeftPosArray&iToposArray也给出了正确的值。谢谢。我读过一些帖子,但从未掌握闭包的窍门。以下是我从您的回答中的理解:setTimeout函数接受'i'参数,以跟踪当前正在运行的循环号。但是,在函数末尾的'}(i));,我有点失去了最后一点;,第三条底线。为什么“i”在这里被乘以?你可以把它想象成i的当前状态保存在函数体中。因此,最后您将不会使用i等于3调用timeout函数。实际上,这个(function(){/…}())是自执行函数的语法。在本例中,函数是匿名的,它只接受一个参数(即i,但与我在循环中喜欢的参数不同,它可能具有不同的值)。我在用“}(I));”因为我想将I作为参数传递给自动执行的匿名函数。这就是它如何将i的当前值“保存”到它的体内。我希望我是清楚的:-)。顺致敬意,非常感谢你抽出时间来做这件事。我一直在想,但是有点挣扎。简而言之,函数(i)中的“i”与循环中上面的“i”不同。然而,(i)乘法与循环中的“i”相同。。。首先,这个匿名函数独立于父函数中的其他代码,除了它末尾的乘法(i)。当然,将函数与(i)相乘不应该像将方法与数字相乘一样有效…@Kayote-不,但是你可以使用
(函数(y){…})(i)
来获得效果嗯,这是我的解决方案,不是吗?@mgechev这是任何人的解决方案,这个问题有数百万个稍微不同形式的重复项。我只是想解释为什么它不起作用。这是一个很好的解释。谢谢你为我澄清这一点@Esailija。