Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: settimeout nie wywołuje się poprawnie
Forum PHP.pl > Forum > Po stronie przeglądarki > JavaScript
Coyot121
Kod
    $("#test").click(function (){loop(4); });
    var i = 0;
    function loop( iHowMany  ){
        
        $("#test").text(i++);
        if ( i < iHowMany ){
            setTimeout("loop( iHowMany )",1000);
        }
    }


w założeniu funkcja ta po naciśnięciu przycisku powinna się powtarzać tak długo dopóki "i" nie będzie mniejsze od 4
Przeszukałem już wiele stron i ciągle nie mogę sobie z tym poradzić. Przy próbie ponownego wywołania funkcji Loop wyskakuje błąd"loop is not defined"

Bardzo proszę o pomoc bo przez to nie mogę kontynuować mojego projektu. ogólnie jako argument będzie podawana tabela z parametrami i po określonym czasie mają one się zmieniać lecz nie mogę przez to przebrnąć
krowal
Spróbuj czegoś takiego:
[JAVASCRIPT] pobierz, plaintext
  1. $("#test").click(function (){
  2. loop(4);
  3. });
  4.  
  5. function loop(amount){
  6. this.interval = null;
  7. var i = 0;
  8. this.interval = setInterval(function(){
  9. $('#test').text(++i);
  10. if (i == amount) clearInterval(this.interval);
  11. }, 1000);
  12. }
[JAVASCRIPT] pobierz, plaintext

Sprawdzone, działa.
nospor
Błąd który dostajesz jest dziwny. Na mój gust błąd powinien brzmieć
iHowMany is not defined

źle wywołujesz funkcję w setTimeout. Powinno być
setTimeout("loop( "+iHowMany+" )",1000);
Coyot121
krowal dzięka użyję twojej wersji

nospor pomimo że wywołałem twoim sposobem wciąż wywala mi błąd "loop is nor defined"

nospor
No to nie pokazujesz w takim razie całego kodu bo to ci podałem działa bez problemu
krowal
Jakby nie było, nospor mimo iż nie dał gotowego kodu czym naraził się na pogardę zakładającego temat miał rację z tym, że błąd powinien być taki: 'iHowMany is not defined' a nie ten, który tu wpisałeś wink.gif
zegarek84
Cytat(nospor @ 25.05.2011, 10:22:31 ) *
No to nie pokazujesz w takim razie całego kodu bo to ci podałem działa bez problemu

zadziała bez problemu ale tylko i wyłącznie wtedy, gdy funkcja loop jest zdefiniowana w globalnym zasięgu (czyli pod window), jeśli jednak funkcja jest zagnieżdżona niżej ten sposób nie zadziała (i wtedy window.loop jest nie zdefiniowany ;] - inna sprawa, że pisze samo loop) - poza tym tą metodę nazwałbym niejawnym używaniem eval'a...

na szybko wystarczyło, jeśli wywołanie obudował by w funkcję anonimową i nie jako tekst:
[JAVASCRIPT] pobierz, plaintext
  1. setTimeout(function(){loop( iHowMany );},1000);
[JAVASCRIPT] pobierz, plaintext


jednak jeśli gdzieś dalej on operuje na zmiennej iHowMany a nie chciał, by się zmieniała powinien tą zmienną przekazać jako parametr - czasami na dynamicznym sterowaniu można podmieniać i definicje metod/funkcji - więc funkcję też można przekazać dla pewności przez callback jeśli jej definicja ma się nie zmieniać:
[JAVASCRIPT] pobierz, plaintext
  1. setTimeout(
  2. (function(callback, arg1){
  3. return function(){callback(arg1);callback = arg1 = null;};
  4. })(loop, arg1)
  5. ,1000
  6. );
[JAVASCRIPT] pobierz, plaintext

przypisanie zmiennych do null'a callback = arg1 = null; nie jest konieczne aczkolwiek lepiej zerować nie potrzebne zmienne ze znikającego zasięgu by zapobiec wyciekowi pamięci w niektórych przeglądarkach...

wszystko też zależy, gdzie dana zmienna jest zdefiniowana, od zasięgu i od tego, czy funkcja przyjmuje argumenty - jeśli nie przyjmuje argumentów a operuje na zmiennych z wyższego poziomu to równie dobrze można zapisać bez cudzysłowia:
Kod
setTimeout(callback, 1000);


wszystkie powyższe przypadki są szybsze od niejawnego eval'a i dają możliwość operowania na zagnieżdżonych zmiennych i funkcjach...
nospor
Cytat
na szybko wystarczyło, jeśli wywołanie obudował by w funkcję anonimową i nie jako tekst:
[JAVASCRIPT] pobierz, plaintext
setTimeout(function(){loop( iHowMany );},1000);
To się wykona od razu a nie po sekundzie. smile.gif

Co do zasięgu to zapewne masz rację.
zegarek84
Cytat(nospor @ 25.05.2011, 11:25:21 ) *
To się wykona od razu a nie po sekundzie. smile.gif

jak niemal każdy na tym forum znasz firebug'a - wklej sobie to do konsoli i luknij na efekty:
[JAVASCRIPT] pobierz, plaintext
  1. var fLoop = function(sMesage){console.log(sMesage);};
  2. var sTxt = 'Pokażę się po 2s === 2000ms a nie od razu ;]';
  3. setTimeout(function(){fLoop(sTxt);},2000);
[JAVASCRIPT] pobierz, plaintext


ku woli wyjaśnienia - function(){} - to jest deklaracja anonimowej funkcji/obiektu - by się on wykonał od razu należało by zapisać (function(){})()... przy okazji w poście wyżej poprawiam błąd gdyż odruchowo wpisałem przy przekazywaniu argumentów function(){}() zamiast właśnie wspomnianego (function(){})() - co też by zadziałało ale nie na wszystkich przeglądarkach

chociaż nie programuję zawodowo to obiektowość w JS (wraz z dziedziczeniem w prototype [nie piszę o bibliotece] bez wywoływania niepotrzebnych konstruktorów przed deklaracją obiektu) i sam JavaScript raczej znam na wylot
nospor
Spoko maroko, nie denerwuj się. Poprostu szybko spojrzałem i nie zauważyłem, że ty tam wkładasz deklarację anonimowej funkcji smile.gif
function(){....}
Z tą funkcją jest jak najbardziej ok i nie potrzeba mi do tego FireBuga smile.gif
Coyot121
Kod
$(document).ready(function(){

inne funkcje  nie związane z tym
    
$("#test").click(function (){loop(4); });
    var i = 0;
    function loop( iHowMany  ){
        
        $("#test").text(i++);
        if ( i < iHowMany ){
            setTimeout("loop( iHowMany )",1000);
        }
    }

    
    
});


nic więcej tam nie było,
ps: czemu miałbym kłamać że mi inny komunikat wyskakuje questionmark.gif
finalnie jak mi to zadziałało do funkcji jest przekazywany parametr mówiący jak liczna jest tabela (można to policzyć ale sobie przekazałem), plus tabela ze ścieżkami do zdjęć. W rezultacie uzyskałem to co chciałem czyli zmianę określonych zdjęć przekazanych przez php. i obojętne mi to było jakim sposobem to zrealizuje, tamten mi nie chciał zadziałać więc użyłem tego co działał

finalnie wyszło to tak:
Kod
$(document).ready(function(){

reszta nie związana z tym
    
    $("#again").click(function (){
        location.reload();        
    });
    
    
});
function loop(amount, tab){
      this.interval = null;
      var i = 0;
      this.interval = setInterval(function(){
        
        $('#showimg').attr("src" , tab[i++]);
         if (i == amount){
             $("#again").css('display','block');
             clearInterval(this.interval);
            
         }
        
      },3000);
    }

może nie wygląda to estetycznie i fachowo ale działa więc chwilowo mi wystarczy tongue.gif
wywołanie tego wygląda jeszcze gorzej ale nie znam się jeszcze za dobrze na łączeniu php i javascriptu
nospor
No, czyli funkcję loop definiowałeś lokalnie, dlatego nie była widziana, jakbyś zdefiniował od razu ją globalnie, czyli poza document.ready to byś dostał błąd o którym ja mówiłem wink.gif
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.