Javascript 使用setTimeout函数&;随机函数。设置类元素动画的步骤
我的调试技能并不能帮助我找出我在这里做错了什么 我希望数组中的每个元素在指定时间后使用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
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。