2014-06-05 35 views
0

我一直在使用setTimeout編程幾天,它在我的主要測試瀏覽器Chrome上工作。一旦我在不同的瀏覽器上查看該功能,Internet Explorer就給我提供了一個問題,根本無法工作。其他瀏覽器也工作。如何解決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 
}); 

這只是代碼的一部分,但我相信問題在於。某些邏輯或語法可能不正確,但這不是我的問題。 10秒後,不應該有setTimeout調用,因爲剩餘時間會是負數,所以確實沒有「無限循環」。使用這個(部分)代碼,它可以在Chrome中完美運行,並且每100毫秒執行一次。在Internet Explorer中,根本沒有任何反應。我在其他堆棧溢出的職位和其他外部資源讀取的語法應該是setTimeout(function() { calleeFunction(); }, time);

我試圖改變var runningFunction = function()function runningFunction()setTimeout功能部分function() { runningFunction(); }它的工作,但在Chrome完全掛起和Internet Explorer最終導致一些堆棧錯誤(我認爲它是在IE中的腳本28)在10秒鐘「無限」呼叫循環期間。

我試過的另一個解決方案是var runningFunction = (function() { ... }());,但是這條線在childWindow.setTimeout(runningFunction, 100);線之前執行。我希望變量只是被聲明,但是不會被執行,直到childWindow.setTimeout行被調用。我不介意把匿名函數放在setTimeout函數中,但我實際上在程序的其他部分使用這個確切的行來重新啓動計時器,而函數本身的長度超過200行,所以我不想複製該程序的多個部分有相同的200行。/

代碼基於奧里奧爾的響應更新

$(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; 
      } 
     } 
    }); 
}); 

提供的小提琴的工作,但它並沒有在網站上運行。基於這種編碼,setTimeout不會被執行的唯一方法是最後一個if語句塊是否爲假。我已經把消息的console.log真正的聲明內,它沒有返回消息,所以我知道IE是執行該塊因此具有去setTimeout線。同樣,使用這種編碼,也會出現與最初發布時相同的情況,Chrome會在每100毫秒的時間內在函數中顯示console.log消息,而IE甚至不會考慮該函數。我真的在這個死路一條。

+0

似乎存在不平衡')'在這一行:'VAR STARTTIME = Date.now()+(dateObject.getTimezoneOffset() - 300)* 60000);'像這樣的語法可能會導致意想不到的結果。如果這不是您的實際代碼,您可能需要編輯您的問題並使用您的實際(正確)代碼進行更新。 – showdev

+1

我提到代碼中的某些語法不正確,因爲這是部分代碼。函數內部的功能工作,而不是IE中的setTimeout部分。 – secretply

+0

'這只是代碼的一部分,但我相信問題在於 - 這個確切的代碼是否會導致您的IE中出現問題?如果沒有,請提供一個樣本。 – James

回答

0

您的代碼有一些問題:

  • 語法錯誤
  • 直到IE9沒有Date.now()支持。您可以使用+new Date()
  • 大多數時候nextCounter是負的,所以延遲功能不能在IE瀏覽器上運行。您可以使用Math.max(0, nextCounter)

這工作:

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

仍然是一樣的情況。我在Chrome中收到控制檯日誌消息,但不在Internet Explorer中收到消息。 – secretply

+0

@secretply您是否嘗試過演示?它適用於IE8。 – Oriol

+0

該演示可用,但不在網站上。我希望它沒有任何關係,我在本地主機上,而不是在一個真實的網站上,我不知道它會如何。我編輯了原始文章,並添加了您的代碼和正在使用的代碼。 – secretply