2012-04-05 88 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); 
     } 
    })();