2014-06-05 2 views
0

J'ai travaillé avec setTimeout sur un certain codage pendant quelques jours et cela a fonctionné sur mon navigateur de test principal, Chrome. Une fois que j'ai vérifié la fonctionnalité sur différents navigateurs, Internet Explorer m'a donné un problème et n'a pas fonctionné du tout. Les autres navigateurs ont également fonctionné.Comment résoudre les problèmes d'Internet Explorer setTimeout?

$(childWindow).load(function() 
{ 
    var dateObject = new Date(); 
    var startTime = Date.now() + (dateObject.getTimezoneOffset() - 300) * 60000; // GMT -5 
    var currentTime = startTime(); 
    var counter = 0; 
    var runningFunction = function() 
    { 
     var remainingTime = Math.round((startTime + 10 * 1000 - (Date.now() + (dateObject.getTimezoneOffset() - 300) * 60000))/1000); 

     if (remainingTime > 0) 
     { 
      // update timer in HTML which is not shown 

      currentTime = Date.now() + (dateObject.getTimezoneOffset() - 300) * 60000; 

      var nextCounter = 100 - (currentTime - (startTime + (counter * 100))); // compensate for browser drifting 

      counter++; 

      childWindow.setTimeout(runningFunction, nextCounter); // try to update nearly at 100 milliseconds every 100 milliseconds 
     } 
    }; 

    childWindow.setTimeout(runningFunction, 100); // initially update at 100 milliseconds 

    // other jQuery coding used 
}); 

Ceci est seulement une partie du code, mais où je crois que le problème réside. Une logique ou une syntaxe peut être incorrecte, mais ce n'est pas le problème que j'ai. Après 10 secondes, il ne devrait pas y avoir d'appel à setTimeout, car remainingTime serait négatif, donc il n'y a pas de "boucle infinie". Avec ce code (partiel), il fonctionne parfaitement dans Chrome et s'exécute toutes les 100 millisecondes. Dans Internet Explorer, rien ne se passe du tout. J'ai lu sur d'autres Stack messages de débordement et d'autres ressources externes que la syntaxe doit être setTimeout(function() { calleeFunction(); }, time);

J'ai essayé de changer var runningFunction = function()-function runningFunction() et la partie de la fonction setTimeout-function() { runningFunction(); } qui fonctionne mais se bloque complètement dans Chrome et Internet Explorer pour aboutir finalement à une pile erreur (je pense que c'était le script 28 dans IE) pendant les 10 secondes "infini" setTimeout boucle d'appel.

Une autre solution que j'ai essayée était var runningFunction = (function() { ... }()); mais cette ligne est exécutée avant la ligne childWindow.setTimeout(runningFunction, 100);. Je veux que la variable soit juste déclarée mais pas exécutée jusqu'à ce que la ligne childWindow.setTimeout soit appelée. Cela ne me dérangerait pas de mettre la fonction anonyme à l'intérieur de la fonction setTimeout mais j'utilise cette ligne exacte dans d'autres parties du programme pour redémarrer la minuterie et la fonction elle-même est longue de plus de 200 lignes donc je ne veux pas copier les mêmes 200 lignes dans plusieurs parties du programme.

code basé sur la réponse de Oriol/Mise à jour

$(childWindow).load(function() 
{ 
    $.post("x.php", { a: "", b: "", c: "" }, function(data) 
    { 
     if (data !== "") 
      $("div:first", childWindow.document).html(data); 
     else 
     { 
      var dateObject = new Date(), 
      startTime = aux(), 
      currentTime, 
      counter = 0; 

      function aux() { 
       return +new Date() + (dateObject.getTimezoneOffset() - 300) * 6e4; 
      } 

      function runningFunction() 
      { 
       console.log('runningFunction'); 

       var currentAux = aux(), 
       remainingTime = Math.round( 10 + (startTime - currentAux)/1e3 ); 

       if (remainingTime > 0) 
       { 
        $("div:first", childWindow.document).html("<div>" + remainingTime + "</div>"); 

        currentTime = currentAux; 

        var nextCounter = Math.max(0, 100 - currentTime + startTime + counter * 100); 
        // compensate for browser drifting 

        counter++; 

        childWindow.setTimeout(runningFunction, nextCounter); 
        // try to update nearly at 100 milliseconds every 100 milliseconds 
       } 
      } 

      $("div:first", childWindow.document).html("<div>Random message.</div>"); 

      if (childWindow.document.hasFocus() && childWindow.outerWidth >= 0.90 * screen.availWidth && childWindow.outerHeight >= 0.90 * screen.availHeight) 
      { 
       var pauseTime = ""; 
       var running = true; 

       childWindow.setTimeout(runningFunction, 100); 
      } 
      else 
      { 
       var pauseTime = startTime; 
       var running = false; 
      } 
     } 
    }); 
}); 

Le violon fourni fonctionne mais il ne fonctionne pas sur le site. Basé sur ce codage, la seule façon setTimeout ne serait pas exécutée est si le dernier bloc d'instruction if est faux. J'ai mis un message de console.log à l'intérieur de la déclaration vraie et il a renvoyé ce message donc je sais que IE exécute ce bloc donc il doit arriver à la ligne setTimeout. Encore une fois, avec ce codage, la même situation se produit comme il a été initialement publié, Chrome affiche le message console.log dans la fonction toutes les ~ 100 millisecondes et IE ne considère même pas la fonction du tout. Je cours vraiment dans une impasse avec ça.

+0

Il semble y avoir un déséquilibre ')' dans cette ligne: 'var = startTime Date.now() + (dateObject.getTimezoneOffset() - 300) * 60000); 'Une telle syntaxe peut provoquer des résultats inattendus. S'il ne s'agit pas de votre code, vous pouvez modifier votre question et la mettre à jour avec votre code actuel (correct). – showdev

+1

J'ai mentionné qu'une certaine syntaxe dans le code n'était pas correcte car il s'agit d'un code partiel. La fonctionnalité à l'intérieur de la fonction fonctionne, mais pas la partie setTimeout dans IE. – secretply

+0

'Ceci est seulement une partie du code, mais où je crois que le problème réside» - donc ce code exact cause le problème dans votre IE? Si non, veuillez fournir un échantillon qui le fait. – James

Répondre

0

Votre code a quelques problèmes:

  • erreurs de syntaxe
  • Jusqu'à IE9 il n'y a pas de soutien Date.now(). Vous pouvez utiliser +new Date()
  • La plupart du temps nextCounter est négatif, donc la fonction retardée ne fonctionne pas sur IE. Vous pouvez utiliser Math.max(0, nextCounter).

Cela fonctionne:

var dateObject = new Date(), 
    startTime = aux(), 
    currentTime, 
    counter = 0; 
function aux() { 
    return +new Date() + (dateObject.getTimezoneOffset() - 300) * 6e4; 
} 
function runningFunction() 
{ 
    console.log('runningFunction'); 

    var currentAux = aux(), 
     remainingTime = Math.round( 10 + (startTime - currentAux)/1e3 ); 

    if (remainingTime > 0) 
    { 
     // update timer in HTML which is not shown 

     currentTime = currentAux; 

     var nextCounter = Math.max(0, 100 - currentTime + startTime + counter * 100); 
     // compensate for browser drifting 

     counter++; 

     childWindow.setTimeout(runningFunction, nextCounter); 
     // try to update nearly at 100 milliseconds every 100 milliseconds 
    } 
}; 

childWindow.setTimeout(runningFunction, 100); 
// initially update at 100 milliseconds 

Demo

+0

Toujours la même situation. Je reçois le message du journal de la console dans Chrome, mais pas dans Internet Explorer. – secretply

+0

@secretply Avez-vous essayé la démo? Cela fonctionne sur IE8 pour moi. – Oriol

+0

La démo fonctionne mais pas sur le site. J'espère que ça n'a rien à voir que je suis sur localhost et pas sur un site web en direct, ce que je ne vois pas comment ça pourrait être. J'ai modifié le post original avec l'ajout de votre code et le code qui est utilisé. – secretply

Questions connexes