2016-08-08 11 views
0

Wenn ich schreibe die html:jQuery ändern html Text von über Array iterieren

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> 
<h1 id="message"> 
</h1> 

und JS:

messages = ["Here", "are", "some", "messages."] 

$(function() { 

    for (var i = 0; i < messages.length; i++) { 
    $('#message').html(messages[i]).delay(1000); 
    } 

}); 

und die Seite laden, ich erwarte, dass jede Zeichenfolge in der Array Show sehen mit einer Verzögerung dazwischen. Alles was ich sehe ist jedoch "Nachrichten". erscheinen. Es scheint, dass die for-Schleife sofort durch jeden Wert im Array iteriert, bevor irgendeine Verzögerung auftritt.

Ich habe eine andere Methode gesehen, um das gewünschte visuelle Ergebnis zu erhalten (How can I change text after time using jQuery?), aber ich würde gerne wissen, warum die frühere Methode nicht funktioniert. Was passiert, wenn dieser Code ausgeführt wird?

+0

delay() ist asynchron, aber die Schleife ist nicht, so dass die Schleife vor der Verzögerung beendet und zeigt Ihnen das letzte Element im Array. Sie müssen eine Rückruffunktion verwenden –

+0

Der Grund für das Erscheinen von "Nachrichten" ist, dass es das letzte Element ist, wenn die Schleife die Iteration über das Objekt beendet. Sie müssen eine andere Variable außerhalb der Schleife erstellen, um das Ganze zu speichern. –

Antwort

1

Beachten Sie, dass jQuery delay speziell für Effekte ist; Methoden wie html verwenden die Effektwarteschlange nicht und sind daher von delay nicht betroffen.

Dies ist ein Problem besser gelöst mit JavaScript native setTimeout Funktion. Es gibt viele Möglichkeiten, dies zu tun; In der Tat, Sie brauchen nicht einmal jQuery!

let messages = ["Here", "are", "some", "messages."]; 
 
let delay = 1000; 
 
let header = document.getElementById("message"); 
 

 
messages.forEach(function(message, i) { 
 
    setTimeout(function() { 
 
    header.innerText = message; 
 
    }, delay * i); 
 
});
<h1 id="message" />

2

So würde ich meine Nachrichtenänderung verzögern.

function delayLoop(delay, messages) { 
 
    var time = 100; 
 

 
    $(messages).each(function(k, $this) { 
 
     setTimeout(function() 
 
     { 
 
      $("#message").html($this); 
 
     }, time) 
 
     time += delay; 
 
    }); 
 
} 
 
delayLoop(1000, ["Here", "are", "some", "messages."]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="message"> 
 
</div>

Alles, was ich war durch eine zusätzliche Verzögerungszeit für jede Nachricht Verzögerung haben. Es funktioniert im asynchronen Modus, so dass es nicht blockiert und die Nachrichten nacheinander angezeigt werden.

EDIT:

Entfernt die .delay vom .html es redundant ist.

+0

Es ist unnötig, sowohl 'setTimeout' als auch' delay' zu verwenden, da beide bereits asynchron sind. Sie können einfach so etwas tun wie '$ (Nachrichten) .Each (Funktion (i, Nachricht) { setTimeout (Funktion() { $ ('# Nachricht').HTML (Nachricht); }, Verzögerung * i); }); ' – Hamms

+0

Danke, dass ich nicht bemerkt habe, dass ich das tat, ich kopiere einfach und kopierte seine Nachrichtenfunktion, weil es keinen Sinn gab, das ganze Ding neu zu schreiben, aber es wurde jetzt repariert, danke. – JQluv

+0

Sie übergeben 'this' auch an den html-Aufruf, obwohl 'this' im setTimeout-Callback nicht definiert ist. – Hamms

0

Sie müssten etwas entlang der Linien von

$(function() { 
    for (var i = 0; i < messages.length) { 
    var done=false; 
    $('#message').html(messages[i]).delay(1000).queue(function(){ 
    done=true; 
    $(this).dequeue(); 
    }); 
    if(done==true){ 
     i++; 
    } 
    } 
}); 
+0

Nach der Antwort von JQluv ist es viel effizienter als meins. Mach weiter und benutze seine. – mmkranz7

0

Vielen Dank für die Antworten und Kommentare - sehr hilfreich.

fand ich auch diesen Beitrag hilfreich: Node.js synchronous loop, und es gab diesen (das funktioniert auch):

function changeText() { 
    var msg = messages.shift(); 
    $('#message').html(msg).show(0).delay(1000).hide(0, function() { 
    if (messages.length > 0) { 
     changeText(); 
    } 
    }); 
} 

(I verwendet .show und .Hide weil ohne sie nur eine der Array-Werte erschienen. Ich bin nicht sicher, warum das ist, aber das ist eine Frage für eine andere Zeit.)