Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [jQuery] ClearInterval nie działa
Forum PHP.pl > Forum > Po stronie przeglądarki
unnamedly
[JAVASCRIPT] pobierz, plaintext
  1. $(".bx-start").click(function() {
  2. if($(".bx-count").length)
  3. {
  4. clearInterval(interval);
  5. $(".bx-count").remove();
  6. }
  7. else
  8. {
  9. $(".bx-window").before("<span class='bx-count'>25</span>");
  10. var howmuch = 25;
  11. var interval = setInterval(function() {
  12. howmuch--;
  13. $(".bx-count").html(""+howmuch+"");
  14. if(howmuch == 0)
  15. howmuch = 25;
  16. }, 1000);
  17. }
  18. });
[JAVASCRIPT] pobierz, plaintext


Czyli klikam w .bx-start i jeśli istnieje .bx-count, to ma czyścić mi timer i usuwać span`a. Jeśli nie istnieje, to tworzy .bx-count i ustawia timer, który odlicza od 25 do 0 i tak w kółko.

Problem w tym, że clearInterval() mi nie działa i nie czyści timeru (każdy kolejny timer przy kliknięciu w .bx-start o (chyba) id "interval" działa w tym samym czasie).

Any ideas?
tolomei
Witaj.

Nie jestem w stanie tego przetestować ale domyślam się że błąd tkwi w porozrzucanych deklaracjach var.
Spróbuj tego - jak coś to zobaczymy ponownie.

[JAVASCRIPT] pobierz, plaintext
  1. $(".bx-start").click(function() {
  2. var howmuch, interval;
  3.  
  4. if($(".bx-count").length)
  5. {
  6. clearInterval(interval);
  7. $(".bx-count").remove();
  8. }
  9. else
  10. {
  11. $(".bx-window").before("<span class='bx-count'>25</span>");
  12. howmuch = 25;
  13. interval = setInterval(function() {
  14. howmuch--;
  15. $(".bx-count").html(""+howmuch+"");
  16. if(howmuch == 0)
  17. howmuch = 25;
  18. }, 1000);
  19. }
  20. });
[JAVASCRIPT] pobierz, plaintext


Ogólnie zalecanym zwyczajem przy pisaniu JS-a jest posiadanie jednej deklaracji var na początku każdej funkcji.
Kolejnym dobrym zwyczajem jest używanie setTimeout() w połączeniu z rekurencją.
Dobrze byłoby także przypisać $(".bx-count") do jakiejś zmiennej na początku funkcji. W tej chwili przy każdym wywołaniu skrypt przeszukuje całe drzewo DOM w poszukiwaniu tego elementu. W twoim skrypcie dzieje się to 3 razy, a potem co sekunde. Przy wspomnianej zmianie tylko raz i koniec.

Znowu gaduła mi się włączyła....

Pozdrawiam!
PrinceOfPersia
to co mu dałeś też raczej nie zadziała. Powinno się wywalić deklarację var... w ogóle poza funkcję click. Inaczej po prostu za każdym razem się będzie tworzyła nowa zmienna interval, a nie o to chodzi.
Chodzi o to, żeby zmienna była nieco "bardziej globalna".
o tak:
Kod
...
var interval;
$(".bx-start").click(function() {
....


EDIT:

Cytat
Kolejnym dobrym zwyczajem jest używanie setTimeout() w połączeniu z rekurencją.

co masz na myśli? Rekurencja to ogólnie nie jest dobry zwyczaj.
tolomei
Przykład:

Zamiast tworzyć funkcję wykorzystującą setInterval() czyli przykładowo:

[JAVASCRIPT] pobierz, plaintext
  1. (function() {
  2. var exampleFunction = function(){
  3. // robię coś tutaj
  4. };
  5.  
  6. setInterval(exampleFunction, 1000);
  7. }());
[JAVASCRIPT] pobierz, plaintext


To tworzę funkcję wywołaną przez setTimeout() z rekurencją czyli:

[JAVASCRIPT] pobierz, plaintext
  1. (function() {
  2. var exampleFunction = function(){
  3. // robię coś tutaj
  4.  
  5. // kolejną linię wykonuję jak skończę powyższe
  6. setTimeout(exampleFunction, 1000);
  7. };
  8.  
  9. setTimeout(exampleFunction, 1000);
  10. }());
[JAVASCRIPT] pobierz, plaintext


Powodem jest fakt(w zależności co robi funkcja), że przy wywołaniu setInterval(exampleFunction, 1000) będzie wykonywania niezależnie od czegokolwiek co sekundę. Teraz w momencie, gdy nasza funkcja dostanie jakiegoś błędu w trakcie działania, niezależnie od tego zostanie wywołana kolejny raz. W takim przypadku błędy mnożą się i w efekcie przeglądarka(w zależności od tego jakiego kalibru operacje wykonuje funkcja) może się zawieszać, a interfejs nie działać poprawnie.

Drugim powodem jest też sytuacja, w której czas między wywołaniami jest bardzo krótki. W takiej sytuacji raz wywołana funkcja może jeszcze nie zakonczyć działań np. na DOMie, a już kolejna funkcja będzie zmieniała to samo co może skutkować różnie.

W przypadku drugiego przykładu powyżej z funkcją setTimeout() w momencie błędu funkcja nie wywoła siebie po raz kolejny. W lepszym przypadku nawet sama funkcja może zadecydować, czy wywoła się kolejny raz czy raczej jest mocno źle i przerwie wywoływanie. setTimeout() także nie wywoła się szybciej niż przed zakonczeniem operacji tak więc druga niepożądana sytuacja też nie wystąpi.
Wadą takiego wzorca jest to, że przed wywołaniem setTimeout() po raz kolejny oprócz tej jednej sekundy oczekiwania dochodzi nam dodatkowy czas wykonywania się operacji wewnątrz funkcji.

Tak więc wzorzec ten ma wady i zalety - należy go stosować adekwatnie do sytuacji.

Jeśli możesz rozwinąć temat to z chęcią się dowiem co o tym myślisz.

Dzięki!
PrinceOfPersia
aha. No tak, ale to tylko pozorna rekurencja, bo w rzeczywistości
nie robisz tak
exampleFunction() -->
exampleFunction() -->
exampleFunction() --->
exampleFunction() --->
--> (może grozić przepełnieniem stosu w skrajnych przypadkach)

tylko tak:
1. exampleFunction() ---> setTimeout() --> return
-- zwrócenie sterowania do przeglądarki --
2. exampleFunction() ---> setTimeout() --> return
-- zwrócenie sterowania do przeglądarki --
3. exampleFunction() ---> setTimeout() --> return


tolomei
Poczytam o tym co napisałeś - takiej wiedzy mi właśnie brakuje.
Mam dużo książek z heliona o JavaScripcie, ale ani słowa tam o czymś takim jak zarządzanie pamięcią itd...
Pisząc o wydajności JS-a autorzy książek zawsze biorą pod uwagę czas wykonywania skryptu i na tym się kończy.
Pogoogluję trochę i może się jeszcze odezwę. Nie chcę robić większego offtopic-a bo BigBrother patrzy, choć to jest bardzo ciekawy temat.

Dzięki! Pozdrawiam.
unnamedly
Zastosowałem się do Waszych rad i zrobiłem tak:
[JAVASCRIPT] pobierz, plaintext
  1. var t;
  2. $(".bx-start").click(function() {
  3. if($(".bx-count").length)
  4. {
  5. clearTimeout(t);
  6. $(".bx-count").remove();
  7. }
  8. else
  9. {
  10. $(".bx-window").before("<span class='bx-count'>25</span>");
  11. var howmuch = 25;
  12. var timer = function() {
  13. howmuch--;
  14. $(".bx-count").html(""+howmuch+"");
  15. if(howmuch == 0)
  16. howmuch = 25;
  17. t = setTimeout(timer, 1000);
  18. }
  19. t = setTimeout(timer, 1000);
  20. }
[JAVASCRIPT] pobierz, plaintext


i działa smile.gif Dzięki wielkie za pomoc!
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.