【问题标题】:Function called by settimeout not endingsettimeout 调用的函数未结束
【发布时间】:2012-09-03 08:13:13
【问题描述】:

问题:在幻灯片中,下面的淡入淡出函数不断调用淡入/淡出函数,请 JsFiddle 运行大约十秒钟以查看问题。在 IE 下不行,不要让 jsfiddle 运行太久,可能会导致浏览器崩溃!

JsFiddle:http://jsfiddle.net/HdYmH/

详细信息(对于那些感兴趣的人):嗨,很抱歉发布一个包含如此大代码块的问题。我仍在学习 javascript,并试图弄清楚如何制作幻灯片。我知道那里有很多 js 幻灯片,但我想将其作为一种学习体验。因此请注意,此代码的某些部分非常糟糕。问题可能与幻灯片的 changeSlide() 方法有关。

我使用 firebug 找出在几秒钟后最明显地调用了哪个方法,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;
    }

}

【问题讨论】:

    标签: javascript settimeout


    【解决方案1】:

    遇到问题了:当不透明度if (opacity < pEndOpac)。 pEndOpac 为 0,因此 0if (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;
    }
    

    【讨论】:

    • 感谢您的回复,我尝试了您建议的更改,不幸的是它没有奏效。我也看不出这与我现在所拥有的有何不同,只有在元素达到最终不透明度时才会清除 timeoutVar。按照我的使用方式,只有在不透明度为 0 时才会清除。
    • @user1490379 你说得对,我错过了一些东西。我已编辑我的答案以显示您遇到的问题。
    • 哇,漂亮的眼睛,我感觉很笨,非常感谢快速调试和响应!
    猜你喜欢
    • 1970-01-01
    • 2021-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多