取消 JavaScript 中的定时循环?

发布于 2024-08-10 02:22:42 字数 1516 浏览 7 评论 0原文

我正在尝试在 JavaScript 中设置一个函数来淡入或淡出我的某些元素页。淡入淡出本身工作正常,但当其中一个试图取消另一个的操作时,我的问题就出现了。

//I know this is ugly, I'm just learning JavaScript again and plan to recode it after I learn some more...
var fadeOut = false

//set out to true to fade out, false to fade in
function fade(out) {
    var steps = 1
    var outSpeed = 100
    var inSpeed = 10
    var timer = 0

    if (out) {
            //fade out
            fadeOut = true
            for ( var i=100; i>=0; i-=steps ) {
                    if ( fadeOut ) {
                            setTimeout("set_el_opacity(" + (i / 100) + ")",
                            timer+=steps
                    } else {
                            break;
                    }
            }
    } else {
            //fade in
            fadeOut = false
            for ( var i=0; i<=100; i+=steps ) {
                    if( !fadeOut ) {
                            setTimeout("set_el_opacity(" + (i / 100) + ")",
                            timer+=steps
                    } else {
                            break;
                    }
            }
    }
}

现在,淡出设置为比淡入运行得慢。我希望用户看到它慢慢淡出,这样他们就知道这是故意的,然后在需要元素时快速淡入(消除屏幕上的一些混乱)当不需要时)。

fade(true) 工作正常,fade(false) 工作正常并且速度更快。当我调用 fade(true) 后不久又调用 fade(false) 时,就会出现问题。淡入淡出相互竞争,然后,由于 fade(true) 调用运行速度更快,因此它首先完成,而 fade(false) 调用则继续将其全部淡出。

我的问题是:我该怎么做才能使 fade(false) 调用取消 fade(true) 调用的循环?

I'm trying to setup a function in JavaScript to fade in or fade out some elements on my page. The fade themselves work fine, but my problem occurs when one of them tries to cancel the actions of the other one.

//I know this is ugly, I'm just learning JavaScript again and plan to recode it after I learn some more...
var fadeOut = false

//set out to true to fade out, false to fade in
function fade(out) {
    var steps = 1
    var outSpeed = 100
    var inSpeed = 10
    var timer = 0

    if (out) {
            //fade out
            fadeOut = true
            for ( var i=100; i>=0; i-=steps ) {
                    if ( fadeOut ) {
                            setTimeout("set_el_opacity(" + (i / 100) + ")",
                            timer+=steps
                    } else {
                            break;
                    }
            }
    } else {
            //fade in
            fadeOut = false
            for ( var i=0; i<=100; i+=steps ) {
                    if( !fadeOut ) {
                            setTimeout("set_el_opacity(" + (i / 100) + ")",
                            timer+=steps
                    } else {
                            break;
                    }
            }
    }
}

Now, the fade out is set to run slower than the fade in. I want the user to see it fade out slowly so they know it's on purpose, and then fade back in quickly if the elements are needed (removing some clutter from the screen when it's not needed).

fade(true) works fine, fade(false) works fine and is faster. My problem occurs when I call fade(true) followed shortly by fade(false). The fades fight with each other and then, since the fade(true) call runs faster it finishes first and the fade(false) call proceeds to fade it all out fully.

My question is: what can I do to make the fade(false) call cancel the loop of the fade(true) call?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

北风几吹夏 2024-08-17 02:22:42

当你设置定时器时:

mytime = setTimeout('function()', 1000);

你可以使用clearTimeout来取消它:

clearTimeout(mytime);

When you set the timer:

mytime = setTimeout('function()', 1000);

you can cancel it by using clearTimeout:

clearTimeout(mytime);
Saygoodbye 2024-08-17 02:22:42

首先,循环触发许多计时器并不是一个好主意。您应该使用 setInterval 或从 setTimeout 处理程序中触发一个新的计时器。

另一种方法是使用一个计时器,它以固定的时间间隔触发并管理所有待处理的效果。您可以决定帧速率并让计时器(“计时器堆栈”)无限期地运行,在每一帧“滴答”——您可以选择在没有待处理效果时启动/停止滴答。

To start with, it's not a good idea to fire many many timers in a loop. You should instead use setInterval or fire off a new timer from your setTimeout handler.

Another approach is to have a single timer which fires off at fixed intervals and manages all pending effects. You can decide on a frame rate and let your timer (a "timer stack") run indefinitely, "ticking" at every frame -- you can optionally start/stop the ticking when there are no pending effects.

浮世清欢 2024-08-17 02:22:42

每当调用 fade() 时,您都应该使用 clearTimeout() 函数取消活动超时。有关超时的更多信息,请查看这篇文章。这是一个基于您提供的代码的简短示例。

var timeoutId = null;

function fade(out) {
    // ...
    // Your variable declarations
    // ...

    // Cancel the active timeout, if any.
    clearTimeout(timeoutId);

    // Record the timeout ID inside your if-else blocks
    if (out) {
        // ...
        timeoutId = setTimeout( ... );
        // ...
    } else {
        // ...
        timeoutId = setTimeout( ... );
        // ...
    }
}

You should cancel the active timeout whenever fade() is called, using the clearTimeout() function. For more information on timeouts, check out this article. Here is a brief example based on the code you provided.

var timeoutId = null;

function fade(out) {
    // ...
    // Your variable declarations
    // ...

    // Cancel the active timeout, if any.
    clearTimeout(timeoutId);

    // Record the timeout ID inside your if-else blocks
    if (out) {
        // ...
        timeoutId = setTimeout( ... );
        // ...
    } else {
        // ...
        timeoutId = setTimeout( ... );
        // ...
    }
}
无力看清 2024-08-17 02:22:42

处理超时循环的最简单方法

function myFunc (terminator = false) {
    if(terminator) {
        clearTimeout(timeOutVar);
    } else {
        // do something
        console.log("loop");
        timeOutVar = setTimeout(function(){myFunc();}, 1000);
    }
}   
myFunc(true); //  -> start loop
myFunc(false); //  -> end loop

SIMPLIEST WAY TO HANDLE TIMEOUT LOOP

function myFunc (terminator = false) {
    if(terminator) {
        clearTimeout(timeOutVar);
    } else {
        // do something
        console.log("loop");
        timeOutVar = setTimeout(function(){myFunc();}, 1000);
    }
}   
myFunc(true); //  -> start loop
myFunc(false); //  -> end loop
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文