2011-03-31 4 views
4

Je suis sûr que cela a été demandé 1000 fois avant, fondamentalement tout ce que je veux faire est de changer le contenu d'un élément de la page pour afficher un message de chargement pendant mon autre code javascript intensif) se termine. Le problème est que le message n'est pas affiché jusqu'à ce que "l'autre traitement JS" soit terminé, ce qui annule complètement son but. un exemple simplifié ...Javascript de base message de chargement tandis que le traitement js termine

<html> 
<head> 
    <title> crappity crapness </title> 
    <script type="text/javascript"> 
     function showMessage(){ 
      document.getElementById("content").innerHTML = "please wait while we waste some time"; 
     } 

     function wasteTime(){ 
      //alert("oh joy"); 
      pausecomp(3000); 
      //alert("marvelous!"); 
     } 

     function pausecomp(millis) 
     { 
      var date = new Date(); 
      var curDate = null; 

      do { curDate = new Date(); } 
      while(curDate-date < millis); 
     } 

    </script> 
</head> 
<body> 
    <div id="content">Blah</div> 
    <br/> 
    <a href="http://www.google.com" onclick="showMessage(); wasteTime();"> link </a> 
</body> 

si je décommenter le « oh joie » d'alerte, le texte dans la div est mis à jour immédiatement. comment puis-je le faire fonctionner sans l'alerte?

Je sais qu'il me manque quelque chose de simple. Merci

Répondre

6

On dirait que vous venez contre le fait que Javascript est mono-thread, mais les navigateurs ne sont pas.

Fondamentalement, vous ne pouvez pas avoir plusieurs morceaux de Javascript en cours d'exécution. Cependant, le navigateur doit encore faire des choses en dehors de l'exécution de Javascript et procède quand il le peut. Le problème est que si la modification du DOM est synchrone (c'est-à-dire que l'exécution de JS s'arrête jusqu'à ce qu'elle soit terminée) ou asynchrone (l'exécution de JS continue) n'est pas définie. La plupart des navigateurs font le dernier. Mais l'exécution JS a toujours une priorité assez élevée et beaucoup de mises à jour DOM sont différées jusqu'à ce que l'exécution de JS doit s'arrêter et attendre. Une boîte d'alerte est un excellent exemple car elle attend l'entrée de l'utilisateur. La manière de faire ce que vous voulez faire est de profiter de setTimeout() qui permet à la partie courante de JS de finir, le navigateur peut alors terminer la mise à jour du DOM, et ensuite il peut exécuter JS en attente d'exécution sur un timeout.

+0

bonne explication, Merci pour cela. J'espérais le faire sans utiliser setTimeout (comme c'était la validation dans le onSubmit d'un formulaire), mais il semble qu'il n'y ait pas d'autre moyen. de toute façon, je suppose qu'un délai d'une milliseconde n'est pas trop mauvais! – hendinas

1

Votre pausecomp(3000) empêche essentiellement le navigateur de se redessiner à cause de la boucle while. Je ferais quelque chose comme ceci:

function wasteTime(){ 
    setTimeout(runNext, 3000); 
} 

function runNext(){ 
    alert("marvelous!"); 
} 
2

Ce qui serait bien si vous pouviez faire serait d'appeler la fonction showMessage de manière asynchrone. Dans d'autres langues, vous pouvez le faire avec des threads, et en HTML5 vous pouvez le faire avec des workers, qui sont conçus exactement pour ce genre de choses, mais pour l'instant vous pouvez simplement utiliser setTimeout, ce qui fait que le code est le premier L'argument s'exécute après un certain temps, permettant au code courant de s'exécuter avant.

changement

onclick="showMessage(); wasteTime();" 

à

onclick="showMessage; setTimeout(wasteTime,5);"> 
+0

oui, c'est tout. J'essayais de le faire sans setTimeout, mais je suppose que ce n'est pas si mal si c'est seulement le retarder d'une milliseconde! Merci. – hendinas

Questions connexes