2013-02-13 8 views
7

Zasadniczo próbuję przechwycić kolekcję znaczników LI i wstawić tekst, aby zasymulować wygląd kogoś, kto pisze listę rzeczy do zrobienia. Działa, ale zapisuje każdy z elementów listy jednocześnie, zamiast czekać. Czy istnieje prosty sposób na osiągnięcie tego? Mam konfigurację skrzypiec JS tutaj: http://jsfiddle.net/fZpzT/, ale kod wygląda tak. Dzięki.jquery .each czekając na zakończenie funkcji przed kontynuowaniem pętli

function addListItems() { 
var str = { 
    listitem1:'personal background check', 
    listitem2:'look into my sketchy neighbor', 
    listitem3:'look up my driving record', 
    listitem4:'pick up milk', 
    listitem5:'wash the car' 
} 

$('.list-container li').each(function(){ 
    var z = $(this).attr('id'); 
    var str2 = str[z]; 
    var delay = 0; 
    for (var i = 0; i <= str2.length; i++) { 
     (function(str2){ 
      delay += 100 + Math.floor(Math.random()*11)*6; 
      setTimeout(function(){ 
       appendStr(str2);  
      },delay); 
     })(str2[i]) 
    } 
    function appendStr(str2) { 
     $('#'+ z).append(str2); 
    } 
}); 
} 
+0

+1 dla dobrze pisemne pytanie i jsfiddle przykład. Nie jestem pewien od razu, jakie jest to * rozwiązanie *, ale jestem prawie pewien, że problemem jest ** nie ** '.each()', ale raczej użycie 'setTimeout()'. Metoda 'setTimeout()' wykonuje się asynchronicznie, co oznacza, że ​​cała pętla kończy się iteracyjnie (nie jednocześnie), ale kończy się * bardzo szybko *, a następnie funkcje obsługi procedur 'setTimeout' zaczynają działać * po * zakończeniu pętli. – Snixtor

+2

Chciałbym szukać [tutaj] (http://api.jquery.com/category/deferred-object/) na kilka pomysłów, jak połączyć te funkcje za pomocą "odroczonego". – Aesthete

+0

Zgadzam się z wyjaśnieniem Snixtora i dodam, że powinieneś prawdopodobnie pomnożyć wartość opóźnienia zależnie od tego, na której pozycji listy jesteś (możesz użyć "each (funkcja (indeks) {...", aby uzyskać indeks). opóźnienie potrzebne dla pierwszej pozycji, ale możesz opóźnić drugi element o 1 sekundę, 3 na 2 sekundy itp., co dałoby efekt jednego elementu listy dodawanego na sekundę –

Odpowiedz

1

Jak o uproszczenie? Użyj dwóch zmiennych do iteracji całej zawartości nieco zmodyfikowanej struktury danych w pojedynczej pętli. Lubię to. http://jsfiddle.net/cXykd/

var strings = 
[ 
    { "id":"listitem1", "text": "write the first item" }, 
    { "id":"listitem2", "text": "write the second item" }, 
    { "id":"listitem3", "text": "write the third item" }, 
    { "id":"listitem4", "text": "write the fourth item" }, 
    { "id":"listitem5", "text": "write the fifth item" }, 
] 

var stringsIndex = 0; 
var textIndex = 0; 

AddString(); 

function AddString(){ 
    if (stringsIndex < strings.length){ 
     if (textIndex >= strings[stringsIndex].text.length) 
     { 
      stringsIndex++; 
      if (stringsIndex == strings.length) 
      { 
       return; 
      } 
      textIndex = 0; 
     } 

     $("#" + strings[stringsIndex].id).append(strings[stringsIndex].text[textIndex]); 
     textIndex++; 

     var delay = 10 + Math.floor(Math.random()*11)*6; 
     setTimeout(AddString, delay); 
    } 
} 
+0

Dzięki Snixtor.Skończyło się na tym rozwiązaniu, ponieważ było to dla mnie najłatwiejsze do zrozumienia, ponieważ musiałem dodać wywołanie zwrotne po wykonaniu całej czynności i dodatkowe funkcje po każdej iteracji przez ciągi. – Brian

4

Bądź opóźnienie łączny: Demo on jsFiddle

var str = { 
    listitem1: 'write the first item', 
    listitem2: 'write the second item', 
    listitem3: 'write the third item', 
    listitem4: 'write the fourth item', 
    listitem5: 'write the fifth item' 
}, cumulativeDelay = 0; 

$('.list-container li').each(function() { 
    var z = $(this).attr('id'); 
    var str2 = str[z]; 
    var delay = cumulativeDelay; 
    for (var i = 0; i <= str2.length; i++) { 
     (function (str2) { 
      delay += 100 + Math.floor(Math.random() * 11) * 6; 
      setTimeout(function() { 
       appendStr(str2); 
      }, delay); 
     })(str2[i]) 
    } 
    cumulativeDelay = delay; 
    function appendStr(str2) { 
     $('#' + z).append(str2); 
    } 
    $(this).css('color', 'red'); 
}); 
+1

nie potrzeba dodatkowej zmiennej. Może po prostu przesunąć linię 'var delay = 0;' poza 'each', aby osiągnąć ten sam wynik. – Jrod

+1

Dzięki Floyd. Poszedłem z rozwiązaniem Snixtor, ponieważ podobało mi się to lepiej niż moje oryginalne, ale kciuki w górę za znalezienie rozwiązania przy użyciu mojego istniejącego kodu. – Brian

2

chciałbym odwrócić funkcjonowanie:

  1. zacząć od strun chcesz pisać,
  2. Dla każdej struny:

    1. Znajdź odpowiednią pozycję z listy (autor: id)
    2. Napisz cały ciąg w stylu maszyny do pisania
    3. Po zakończeniu wykonaj następną iterację.

      var strings = [ 
          'personal background check', 
          'look into my sketchy neighbor', 
          'look up my driving record', 
          'pick up milk', 
          'wash the car' 
      ]; 
      
      function iterate(strings, idx) 
      { 
          if (idx >= strings.length) { return; } 
      
          var id = 'listitem' + (idx + 1), 
          el = document.getElementById(id); 
      
          typewriter(el, strings[idx], 0, function() { 
          iterate(strings, idx + 1); 
          }); 
      } 
      
      function typewriter(el, str, idx, cb) 
      { 
          if (idx >= str.length) { 
          return cb(); 
          } 
      
          setTimeout(function() { 
          el.innerText = str.substr(0, idx + 1); 
          typewriter(el, str, idx + 1, cb); 
          }, 100 + Math.floor(Math.random() * 11) * 6); 
      } 
      

Demo

+0

Dziękuję Jack. Skończyłem z rozwiązaniem Snixtor, ale twoje podejście było również doskonałe. – Brian

Powiązane problemy