首页 > 解决方案 > 在循环内的 IIFE 内取消 setTimeout

问题描述

我有一个函数可以单击 dom 元素以显示和隐藏它们。

该函数正常工作并循环通过我的 dom 元素但是由于我正在使用的 IIFE,一旦我调用该函数,我就无法停止 setTimeout。

我在全局空间中添加了一个变量以跳出循环,但是 setTimeout 已经启动,因此它永远不会停止。我还尝试使用真/假标志为第一个 setTimeout 分配一个名称,以尝试在循环中捕获并停止 setTimeout 的下一次迭代,但是当我尝试停止 setTimeout 时控制台日志继续时,这没有成功.

function cycleSlides() {

    var slides = [1,2,3,4]
    var closeSlide = $(".close"); 

        for(var i = 0; i < slides.length; i++) {
            (function() {
                var x = i;

                setTimeout(function() {

                    if(x == 0) {
                        console.log("slides[x].click()")// first slide
                    } 
                    else {
                        setTimeout(function() { console.log("closeSlide.click()") }, 1000) // timeout for animation to finish when clicked
                        setTimeout(function() { console.log("slides[x].click()") }, 2000) // timeout for animation to finish when clicked
                    }

                    // CLOSE LAST SLIDE
                    if(x == slides.length - 1 ) {
                        setTimeout(function() {
                            console.log("closeSlide.click()")
                        }, x * 1000)
                    }
                }, x * 3000)
            }(i))
        }
     }

标签: javascriptjquery

解决方案


setTimeout()返回一个超时 ID,可以传递给clearTimeout()以取消超时。您可以将调用返回的超时 ID 存储setTimout()在一个数组中。然后,当您想取消它们时,clearTimeout()使用值调用并清除数组。以下是该代码的样子:


var timeouts = [];

function cancelTimeouts() {
    for (var i = 0; i < timeouts.length; i++) {
        clearTimeout(timeouts[i]);
    }

    timeouts = []
}

function cycleSlides() {

    var slides = [1,2,3,4]
    var closeSlide = $(".close"); 

        for(var i = 0; i < slides.length; i++) {
            (function() {
                var x = i;

                timeouts.push(setTimeout(function() {

                    if(x == 0) {
                        console.log("slides[x].click()")// first slide
                    } 
                    else {
                        timeouts.push(setTimeout(function() { console.log("closeSlide.click()") }, 1000)) // timeout for animation to finish when clicked
                        timeouts.push(setTimeout(function() { console.log("slides[x].click()") }, 2000)) // timeout for animation to finish when clicked
                    }

                    // CLOSE LAST SLIDE
                    if(x == slides.length - 1 ) {
                        timeouts.push(setTimeout(function() {
                            console.log("closeSlide.click()")
                        }, x * 1000))
                    }
                }, x * 3000))
            }(i))
        }
     }

推荐阅读