DaBarny: JQuery - setTimeout in For-Schleife

Ich habe folgenden Code:

$(document).ready(function(){
  $("#start").click(function(){
    for (i = 1; i <= 16; i++) {
      setTimeout(function() {
        $(".sabbl" + i).funktion({lalalal...});
      }, 500);
    }
  });
});

Nun, soll eine Animation ausgeführt werden, und diese gleich 16 mal, nur jede mit 500 millisekunden verzögerung nach der verherigen.

Mein Problem ist, das die Animation nicht ausgeführt wird, hab ich etwas falsch gemacht mit der setTimeout-Funktion?

Danke

  1. Hi,

    $("#start").click(function(){
        for (i = 1; i <= 16; i++) {
          setTimeout(function() {
            $(".sabbl" + i).funktion({lalalal...});
          }, 500);

    Nun, soll eine Animation ausgeführt werden, und diese gleich 16 mal, nur jede mit 500 millisekunden verzögerung nach der verherigen.

    Mein Problem ist, das die Animation nicht ausgeführt wird, hab ich etwas falsch gemacht mit der setTimeout-Funktion?

    Mach dir bitte erst mal klar, was genau setTimeout macht.

    Du hast keine Verzögerung zwischen den Aufrufen, sondern du legst lediglich einen Aufruf auf den Ausführungsstapel mit der Bitte „in 500 Millisekunden das hier ausführen“ - und das machst du 16 mal.

    MfG ChrisB

    --
    RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
    1. Dann müsste dies aber doch funktionieren O_o

      1. Hi,

        Dann müsste dies aber doch funktionieren O_o

        nein - bzw. ja, aber nicht so, wie du es dir vorstellst.
        Stell dir vor, du rufst 4mal direkt hintereinander den Zimmerservice an und sagst, dass du in einer Stunde eine Kanne Kaffee aufs Zimmer haben möchtest. Bekommst du nun jede Stunde eine Kanne Kaffee? Oder doch eher 4 Kannen nach einer Stunde?

        So long,
         Martin

        --
        F: Was ist schneller: Das Licht oder der Schall?
        A: Offensichtlich der Schall. Wenn man den Fernseher einschaltet, kommt immer erst der Ton, und dann erst das Bild.
        Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
        1. Und wie kann ich dann demnach meinen code umformen?

          ^^

          1. Und wie kann ich dann demnach meinen code umformen?

            Indem du die Zeitverzögerung mit dem Zähler der Schleife mulitiplizierst.

      2. Hi,

        Dann müsste dies aber doch funktionieren O_o

        Wenn du dich jetzt hinstellst, und sagst, „in 24 Stunden werde ich auf's Klo gehen“, dann gehst du morgen um diese Zeit auf's Klo, fein.
        Wenn du das jetzt gleich sechzehn mal hintereinander machst - dann heißt das nicht, dass du gute zwei Wochen lang sehr regelmäßig dein Geschäft machen wirst, sondern nur, dass du morgen um diese Zeit sechzehn mal hintereinander die Spülung betätigen wirst.

        MfG ChrisB

        --
        RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
  2. Hallo,

    1.) siehst du den Unterschied zwischen function und funktion?
    2.) und was soll das lalalala bewirken?

    $(document).ready(function(){
      $("#start").click(function(){
        for (i = 1; i <= 16; i++) {
          setTimeout(function() {
            $(".sabbl" + i).funktion({lalalal...});
          }, 500);
        }
      });
    });

    Gruß

    Nerdi

  3. [D]ein Problem ist, [...]

    ... dass du ein Framework verwendest aber alles zu Fuß machen willst und an der fx-queue vorbeiprogrammierst.

    Du solltest dich ernsthaft mit each(), delay() und queue() auseinandersetzen.

    Anstatt sabbl1 bis sabbl16 hast du nur Elemente die der Klasse sabbl angehören (oder noch besser gleich einen sinnvolleren Selektor wo du nicht alles mit Klassen zuballern musst). Dann sieht das so aus:

    $('#start').click(function() {  
      $('.sabbl').each(function() {  
        $(this).delay(500).queue(function() {  
          // whatever  
        });  
      });  
    });
    
    1. $(this).delay(500).queue(function() {

      Das hier ist natürlich unsinn - je iteration der each-Methode muss natürlich das 500 mit dem Zähler multipliziert werden

      Sieht so aus:

      $('#start').click(function() {
        $('.sabbl').each(function(index) {
          $(this).delay(500 * (index+1)).queue(function() {
            // whatever
          });
        });
      });

      1. $('#start').click(function() {
          $('.sabbl').each(function(index) {
            $(this).delay(500 * (index+1)).queue(function() {
              // whatever
            });
          });
        });

        Ich würde das mit einer Kette von setTimeouts lösen:

        $('#start').click(animate);  
        function animate () {  
           var $elems = $('.sabbl'),  
               i = 0,  
               l = $elems.length;  
           step();  
           function step () {  
              $elem = $elems.eq(i);  
              // Whatever  
              i++;  
              if (i < l) {  
                 setTimeout(step, 500);  
              }  
           }  
        }
        

        (ungetestet)

        Der Vorteil davon ist, dass der Payload den nächsten Schritt verzögert. Wenn ich mich richtig erinnere sorgt das für gleichförmigere Animationen. Animations-Frameworks wie Émile so. Somit ist auch ausgeschlossen, dass sich mehrere Step-Funktionen im Event-Loop aufstauen, wenn der step einmal länger als der Intervall braucht.

        Wenn man unbedingt jQuerys Animation Queue verwenden will, kann man natürlich $elems.delay(500).queue(step) statt setTimeout schreiben.

        Mathias