2012-09-03 59 views
1

問題:在幻燈片放映中,下面的fade函數一直在調用fadein/out函數,請JsFiddle並運行約10秒鐘以查看問題。在IE中不起作用,不要讓jsfiddle運行時間過長,否則可能會導致瀏覽器崩潰!settimeout調用的函數沒有結束

的jsfiddle:http://jsfiddle.net/HdYmH/

詳細信息(對於那些有興趣):你好,很抱歉發佈提問如此大的代碼塊。我仍在學習JavaScript,並試圖弄清楚如何製作幻燈片。我知道那裏有很多js幻燈片,但我想把它看作一個學習體驗。所以要警告的是,這些代碼的一部分非常糟糕。問題可能與幻燈片的changeSlide()方法有關。

我用螢火蟲找出哪種方法被調用最明顯,幾秒鐘後fadeOut將被稱爲20k +次:

// Generic fade function that fades in or out 
function fade(pElem, pStartOpac, pEndOpac, fps, sec) { 
    if ((typeof (pElem) !== "string") || (typeof (pStartOpac) !== "number") 
      || (typeof (pEndOpac) !== "number") || (typeof (fps) !== "number") 
      || (typeof (sec) !== "number")) { 
     console.log("Parameters incorrect format has to be (string) Element Id, (double) Starting Opacity, (double) End Opacity, (integer) frames per second, (integer) seconds to run"); 
     return; 
    } 
    // The CSS opacity property only works from 1 to 0 
    if (pStartOpac < 0) { 
     pStartOpace = 0; 
    } 
    if (pStartOpac > 1) { 
     pStartOpac = 1; 
    } 
    if (pEndOpac < 0) { 
     pEndOpac = 0; 
    } 
    if (pEndOpac > 1) { 
     pEndOpac = 1; 
    } 

    // Stop the fps from going over 60 or under 1 (The eye will barely notice 
    // improvements above 60fps and fractional fps are not supported) 
    if (fps > 60) { 
     fps = 60; 
    } 
    if (fps < 1) { 
     fps = 1; 
    } 

    var totalFrames = (fps * sec); 
    var opacityChangePerSecond = (Math.abs(pStartOpac - pEndOpac)/sec); 
    var opacityChangePerFrame = (opacityChangePerSecond/fps); 
    var timeOutInterval = 1000 * (1/fps); 

    // console.log("totalFrames: "+totalFrames); 
    // console.log("Opacity change per second: " + opacityChangePerSecond); 
    // console.log("Opacity change per frame: " + opacityChangePerFrame); 
    // console.log("Time out interval: " + timeOutInterval + " milliseconds"); 

    var opacity = pStartOpac; 
    var timeoutVar; 
    var elemId = document.getElementById(pElem); 
    elemId.style.opacity = opacity; 

    if (pStartOpac < pEndOpac) { 
     fadeIn(); 
     return; 
    } else { 
     fadeOut(); 
     return; 
    } 

    function fadeIn() { 
     opacity = opacity + opacityChangePerFrame; 
     if (opacity > pEndOpac) { 
      clearTimeout(timeoutVar); 
      return; 
     } 
     elemId.style.opacity = opacity; 
     timeoutVar = setTimeout(fadeIn, timeOutInterval); 
     return; 
    } 

    function fadeOut() { 
     if (opacity < pEndOpac) { 
      clearTimeout(timeoutVar); 
      return; 
     } 
     opacity = opacity - opacityChangePerFrame; 
     if (opacity < 0) { 
      opacity = 0; 
     } 
     elemId.style.opacity = opacity; 
     timeoutVar = setTimeout(fadeOut, timeOutInterval); 
     return; 
    } 

} 

回答

0

得到了問題:當Opacity獲取< 0將其設置爲0,然後執行:if (opacity < pEndOpac)。 pEndOpac爲0因此,0 < 0的計算結果爲false,並且永遠不會清除超時。解決的辦法是做if (opacity <= pEndOpac)

function fadeIn() { 
    opacity = opacity + opacityChangePerFrame; 
    if (opacity >= pEndOpac) { 
     clearTimeout(timeoutVar); 
     return; 
    } 
    elemId.style.opacity = opacity; 
    timeoutVar = setTimeout(fadeIn, timeOutInterval); 
    return; 
} 

function fadeOut() { 
    if (opacity <= pEndOpac) { 
     clearTimeout(timeoutVar); 
     return; 
    } 
    opacity = opacity - opacityChangePerFrame; 
    if (opacity < 0) { 
     opacity = 0; 
    } 
    elemId.style.opacity = opacity; 
    timeoutVar = setTimeout(fadeOut, timeOutInterval); 
    return; 
} 
+0

感謝您的答覆,我想你的建議的變化,遺憾的是它沒有工作。我也看不出與現在有什麼不同,只有當元素達到最終不透明度時纔會清除timeoutVar。隨着我使用它的方式只有當不透明度爲0時才被清除。 – ksrb

+0

@ user1490379你是對的,我錯過了一些東西。我編輯了我的答案以顯示您有問題。 – mornaner

+0

Wow漂亮的眼睛,我感覺很蠢,很感謝快速調試和響應! – ksrb