2010-07-20 12 views
8

Używam jQuery do ustawienia timera lub pętli interwału na kilku elementach, aby sprawdzać je co kilka sekund. Próbowałem ustawić timer i sprawdzić, czy powinienem go zrestartować, ustawić i interwałować i sprawdzić, czy powinienem go zatrzymać.Timer javascript lub interwały utworzone w pętli przy użyciu zamknięcia

Chociaż uproszczone, to jest po prostu to, czego potrzebuję:

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]); 
    } 
} 

Dokumentach interpretacyjnych dla elementów klasy są ID_1, ID_2, id_3. Ale po prostu otrzymuję 3 alerty, które dają id_3. W moim kodzie zacząłem próbować przekazać "to", ale upraszczałem go, aby dowiedzieć się o problemie.

Jak mogę go pobrać, aby za każdym razem skopiować zmienną pod nowy adres? Wiem, że potrzebuję użyć zamknięć. Wydaje się, że odwołuje się do drugiego var no mater co.

Próbowałem upraszczając go do pętli z timerów tak:

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

Ale myślę, że tylko co mój problem gorzej i że nie wydają się nic zrobić.

Szukałem wcześniejszych pytań, ale większość z nich jest wypełniona mnóstwem dodatkowego kodu, zamiast ograniczać go do konkretnego problemu i rozwiązywać w inny sposób. Chciałbym zrozumieć, jak to działa lepiej, aby ten przykład działał. Udało mi się, pisząc to, wymyślić, że mogę ustawić timer za pomocą funkcji pomocniczej.

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

Jak można tego dokonać bez tego? Czy jest jakiś lepszy sposób?

+3

Naprawdę powinieneś zadeklarować * wszystkie * twoje lokalne zmienne z 'var', włączając w to indeksy pętli. – Pointy

Odpowiedz

3

Jesteś w zamknięciu podczas korzystania każda, po prostu zapomnieli var aby zmienna prywatnych w zakresie funkcji

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

* uderza w czoło * Właściwie próbowałem var w różnych miejscach, z wyjątkiem tego, ha. – phazei

4

mają zmienne „myid” lokalne do funkcji anonimowej,

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

Czy chcesz uruchomić myFunction na każdym dopasowanym elemencie co trzy sekundy?

Spróbuj tego:

$('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); 
     } 
    } 
}; 

Jeśli warunek jest spełniony w something() skończysz, jeśli nie spodziewają się do funkcji uruchomić ponownie w 3 sekundy z tego samego elementu, jak wcześniej. Możesz wywoływać to tyle razy, ile chcesz na różnych elementach, każde połączenie ma swoją własną elem.

Wolę przekazywać przedmioty takie jak elem i opóźniać pracę z ich wnętrzami do ostatniej możliwej chwili. Niech something() martwi się o identyfikator lub cokolwiek innego.

Żaden z pozostałych gimnastyki z tablicy asocjacyjnej (zamiast new Array() można po prostu użyć {}) lub clearInterval lub ID użytkownika są konieczne.

Aby faktycznie rozwiązać twoje rozwiązanie, jak powiedział Marimuthu, zostawiłeś var z deklaracji myID, co oznacza, że ​​jest globalne i jest nadpisywane w każdej iteracji.Powoduje to, że gdy setInterval wywołuje myFunction zamiast uzyskać unikalny lokalny myID przez zamknięcie, otrzymasz globalny, który został już nadpisany czasy umpty.

Powiązane problemy