2012-04-05 60 views
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秒钟一个循环,除非你把光标移动幻灯片股利。当他们删除光标,然后再次超时!

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

编辑:

这个循环伟大的,但上落徘徊导致函数运行多个次:

// 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); 

     }); 

回答

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); 

OR

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); 
    }); 

文档

1

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

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

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

您还会注意到我没有在'changeSlide'附近引用引号,并且我丢弃了这些parens。将一个字符串传递给setTimeout时,使用eval()。一般来说,eval()是建议避免的。所以,相反,我们将它传递给函数的直接引用(不带引号)。我们做使用括号,因为这会实际调用changeSlide()向右走,而不是推迟执行到的setTimeout(并会通过,作为参数传递给setTimeout的,changeSlide的结果())

编辑:让它继续运行,你必须在每次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); 
}); 
+0

酷我已经根据你的答案改变了代码,但它仍然没有循环超时? – Cameron 2012-04-05 15:23:40

+0

关键是在每个changeSlide结束时再次调用setTimeout,它将排队等待下一个更改。你也可以使用setInterval,重复使用,而不是一次 – Matt 2012-04-05 15:25:02

0

我想你需要的setInterval,而不是setTimeout的,因为:

的setTimeout(表达式,超时);在超时后运行一次代码/功能

setInterval(expression,timeout);间隔运行代码/函数,并在它们之间有超时的长度

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); 
    }); 
+0

呵呵,我不使用jQuery,但是我觉得我没有使用悬停功能。很高兴知道......但我可能会忘记。 :) – 2012-04-05 15:43:23

0

你的问题可能是鼠标悬停事件。 mouseover事件会出现泡泡,所以如果你有一个嵌套的HTML结构,那么这个事件可能会被多次调用。 如果您使用的是jQuery,则应该使用鼠标事件事件,该事件只会为该元素调用一次。

在另一个笔记上,不是使用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); 
     } 
    })();