Si j'écris le html:

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

Et le JS:

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

$(function() {

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

});

Et charger la page, je m'attends à voir chaque chaîne du tableau apparaître avec un retard entre les deux. Cependant, tout ce que je vois, c'est des «messages». apparaître. Il semble que la boucle for parcourt immédiatement chaque valeur du tableau avant d'effectuer un délai.

J'ai vu une autre méthode pour obtenir le résultat visuel souhaité (Comment peut-on Je change le texte après avoir utilisé jQuery?), mais je voudrais savoir pourquoi la méthode précédente ne fonctionne pas. Que se passe-t-il lorsque ce code est exécuté?

0
Jacquen 9 août 2016 à 00:55

4 réponses

Meilleure réponse

Notez que delay de jQuery est spécifiquement pour les effets; des méthodes comme html n'utilisent pas la file d'attente d'effets et ne sont donc pas affectées par delay.

Il s'agit d'un problème mieux résolu avec le setTimeout fonction. Il y a plusieurs façons de procéder; en fait, vous n'avez même pas besoin de 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" />
1
Hamms 8 août 2016 à 22:31

Vous auriez besoin de quelque chose comme

$(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
mmkranz7 8 août 2016 à 22:08

C'est ainsi que je retarderais la modification de mon message.

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>

Tout ce que j'ai fait, c'est pour chaque retard de message d'un délai supplémentaire. Il fonctionne en mode asynchrone donc ce n'est pas le blocage de l'interface utilisateur et les messages s'afficheront une seconde après l'autre.

ÉDITER:

Suppression du .delay du .html, il est redondant.

2
JQluv 9 août 2016 à 16:25

Merci pour les réponses et commentaires - très utiles.

J'ai également trouvé ce message utile: Boucle synchrone Node.js, et à partir de cela, il a écrit ceci (qui fonctionne également):

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

(J'ai utilisé .show et .hide car sans eux, une seule des valeurs du tableau est apparue. Je ne sais pas pourquoi, mais c'est une question pour une autre fois.)

0
Community 23 mai 2017 à 10:28