0

我有以下代码:

// After 8 seconds change the slide...
        var timeout = setTimeout("changeSlide()", 8000);

        $('div.slideshow').mouseover(function() {

            // If the user hovers the slideshow then reset the setTimeout
            clearTimeout(timeout);
        });

        $('div.slideshow').mouseleave(function() {

            clearTimeout(timeout);
            var timeout = setTimeout("changeSlide()", 8000);

        });

我想要发生的是让函数 changeSlide 每 8 秒循环运行一次,除非有人悬停在幻灯片 div 上。当他们删除光标然后再次超时!

然而,循环只发生一次,悬停不会停止超时或再次启动它:/

编辑:

这循环很好,但悬停打开和关闭会导致函数运行多次:

// After 8 seconds change the slide...
        var timeout = setInterval(changeSlide, 2000);

        $('div.slide').mouseover(function() {

            // If the user hovers the slideshow then reset the setTimeout
            clearInterval(timeout);
        });

        $('div.slide').mouseleave(function() {

            clearInterval(timeout);
            var timeout = setInterval(changeSlide, 2000);

        });
4

5 回答 5

1

你在这里有几个问题。首先,当您设置超时时,如果您可能想要停止它,则需要将该函数调用的返回存储到一个变量中。

    var slide_timer = setTimeout(changeSlide, 8000);

其次,当你调用clearTimeout(而不是clearInterval)时,你需要传递一个参数。什么论据?你调用时存储的那个变量setTimeout

        clearTimeout(slide_timer);

第三,当你使用时setTimeout,它只会触发一次。setInterval会继续开火,然后你会用clearInterval它来阻止它。

使用间隔而不是超时存在时间问题。浏览器对它们的处理方式略有不同,了解差异并使用正确的方法可能对您的代码很重要。如果您使用间隔,因为它们只触发一次,您必须在每次触发时重新建立超时。

var slide_timer = setTimeout(function () {
    changeSlide();
    var slide_timer = setTimeout(changeSlide, 8000);
}, 8000);

或者

var slide_timer = setTimeout(changeSlide, 8000);
...
function changeSlide() {
   ... your code ...
    var slide_timer = setTimeout(changeSlide, 8000);
}

(我更喜欢前一种方法)

最后,无论您使用超时还是间隔,都不要将字符串传递给setTimeout,而是传递函数引用。请参阅上面的示例代码,或者像这样:

var slide_timer = setTimeout("changeSlide()", 8000); // <--- DON'T
var slide_timer = setTimeout(changeSlide, 8000);     // <--- DO
var slide_timer = setTimeout(function () {           // <--- DO
    changeSlide() ;
    // other script
}, 8000); 

把它们放在一起:

// After 8 seconds change the slide...
    var slide_timer = setTimeout(changeSlide, 8000);
    $('div.slideshow').hover(function() {
        // If the user hovers the slideshow then reset the setTimeout
        clearTimeout(slide_timer);
    }, function() {
        slide_timer = setInterval(changeSlide, 8000);
    });

文档

于 2012-04-05T15:29:31.537 回答
1

当您指定 setTimeout(或 setInterval)时,它会返回一个值,然后用于 clearTimeout 和 clearInterval。正确用法如下:

var timeout = setTimeout(changeSlide, 8000);
clearTimeout(timeout);

另请注意,我使用的是 clearTimeout,而不是 clearInterval。

您还会注意到我没有在“changeSlide”周围加上引号,并且我删除了括号。将字符串传递给 setTimeout 时,使用 eval()。通常,建议避免使用 eval()。因此,相反,我们将函数的直接引用传递给它(不带引号)。我们使用括号,因为这实际上会立即调用 changeSlide(),而不是将执行推迟到 setTimeout(并且会将 changeSlide() 的结果作为参数传递给 setTimeout)

编辑:要让它连续运行,您必须在每次 changeSlide 调用后再次调用 setTimeout 。setTimeout 运行一次。作为替代方案,您可以使用 setInterval,它会自动重复。对 setInterval 的一个警告是,如果间隔太短并且它调用的回调需要很长时间才能运行,那么您最终可能会得到一堆间隔排队等待一个接一个地执行,没有延迟。8 秒的间隔可能不会遇到这个问题。

编辑2:

var timeout;
var changeSlide = function(){
   // do something to change slides
   clearTimeout(timeout);
   timeout = setTimeout(changeSlide, 8000);
}

// queue up the first changeSlide, all others happen inside changeSlide
timeout = setTimeout(changeSlide, 8000);

$('div.slideshow').mouseleave(function()  {
    clearTimeout(timeout);
    var timeout = setTimeout(changeSlide, 8000);
});
于 2012-04-05T15:18:24.097 回答
0

最后,这是最好的(但我不会接受这是我的答案,因为是其他人帮助我达到了这一点)

// After 8 seconds change the slide...
    var slide_timer = setInterval(changeSlide, 2000);
    $('div.slideshow').hover(function() {
        // If the user hovers the slideshow then reset the setTimeout
        clearInterval(slide_timer);

    }, function() {
        slide_timer = setInterval(changeSlide, 2000);
    });
于 2012-04-05T15:40:55.617 回答
0

我认为您需要 setInterval 而不是 setTimeout,因为:

setTimeout(表达式,超时);超时后运行代码/函数一次

setInterval(表达式,超时);以间隔运行代码/函数,它们之间的超时长度

于 2012-04-05T15:23:14.830 回答
0

您的问题可能是鼠标悬停事件。mouseover 事件会冒泡,因此如果您有嵌套的 HTML 结构,则该事件可能会被多次调用。 如果您使用 jQuery,则应使用mouseenter事件,该事件只会为元素调用一次。

另一方面,不要使用 setInterval ,而是使用 setTimeout 模式。像这样的东西:

    //Immediately Invoked Function Expression that gets called immediately
    (function() {
        //Make the initial call to your setTimeout function
        repeat();
        //Function will constantly be called
        function repeat() {
            setTimeout(function() {
                //(Put your conditional logic here)
                console.log('test');
                repeat();
            }, 2000);
        }
    })();
于 2012-04-05T15:57:11.880 回答