2010-07-20 52 views
8

我正在使用jQuery在几个元素上设置一个定时器或间隔循环来检查它们每隔几秒钟。我试过设置一个计时器并检查是否应该重新启动计时器,或者设置和间隔并检查是否应该停止它。javascript定时器或使用闭包在循环中创建的时间间隔

虽然简化了,这基本上就是我需要:

var mytimers = new Array(); 
$('div.items').each(function() { 
    myID = $(this).attr('id'); 
    mytimers[myID] = setInterval(function() { myFunction(myID) } , 3000) 
}); 
function myFunction(param) { 
    alert(param); 
    if (something()) { 
     clearInterval(mytimers[param]); 
    } 
} 

该ID的类项目ID_1,ID_2,ID_3。但我只是得到3个警报全部给予id_3。在我的代码中,我开始尝试通过'this',但不断地简化它以找出问题。

我怎样才能得到它每次复制变量到一个新的地址?我知道我需要使用闭包。它似乎引用了其他var没有什么关系。

我试了一下,象这样的定时器简化到一个循环:

function tester(item) { 
    return function() { 
     alert(item); 
    }; 
} 
for(x=1;x<=3;x++) { 
    setTimeout('(function() { tester(x) })(x)' , 3000); 
} 

但我觉得我只是在做我的问题变得更糟,并且似乎并没有做任何事情。

我已经搜索过以前的问题,但大多数都充满了大量额外的代码,而不是将其缩减到特定问题并以其他方式解决。 我想了解这个例子如何工作更好。在写这篇文章的时候,我的确做到了,我想通过帮助功能来启动计时器。

function tester(item) 
    alert(item); 
function myTimer(item) 
    setInterval(function() { tester(item); }, 3000); 
for(x=1;x<=3;x++) 
    myTimer(item); 

这怎么能没有这样做呢?有更好的方法吗?

+3

你真的应该用'var'声明所有你的局部变量,包括循环索引。 – Pointy 2010-07-20 20:35:05

回答

3

你在一个封闭时使用的每个,你只是忘记了变种,让您的私有变量的函数范围

var mytimers = new Array(); 
$('div.items').each(function() { 
    **var** myID = $(this).attr('id'); 
    mytimers[myID] = setInterval(function() { myFunction(myID) } , 3000) 
}); 
function myFunction(param) { 
    alert(param); 
    if (something()) { 
     clearInterval(mytimers[param]); 
    } 
} 
+0

*打了额头*我实际上在各种地方都尝试过var,只有一个,哈哈。 – phazei 2010-07-20 23:23:26

4

具有可变“身份识别码的本地匿名函数,

var myID = $(this).attr('id'); 
1

因此,您希望每三秒对每个匹配元素运行myFunction?如果something()条件满足就大功告成了,如果不是功能安排其自身又在3秒钟,同样的元素之前运行

$('div.items').each(myFunction(this)); 

var myFunction = function(elem) { 
    return function() { 
     if (something(elem)) { 
      //return or do something with elem 
     } else { 
      window.setTimeout(myFunction(elem), 3000); 
     } 
    } 
}; 

试试这个。您可以根据需要在不同的元素上多次呼叫此号码,每个呼叫都有自己的elem

我更喜欢传递像elem这样的对象,并延迟使用它们的内部直到最后一刻。让something()担心身份证或其他。

没有其他体操与联合阵列(而不是new Array(),你可以只使用{})或clearInterval,或ID是必要的。

要真正解决您的解决方案,如Marimuthu说,你离开varmyID申报,这意味着其全球和它被覆盖每个迭代。结果是,当setInterval调用myFunction而不是通过闭包获得唯一的本地myID时,会得到已被覆盖空号的全局变量。