簡體   English   中英

setInterval在Chrome上無法正常工作

[英]setInterval not working properly on Chrome

我有一個自定義的幻燈片對象,用於執行名稱在網站上指示的常用內容。 除了當我在Chrome中切換標簽頁並返回到網站標簽頁之外,所有其他操作都很好。 發生這種情況時,無論給定的setInterval間隔如何,幻燈片放映都會變得瘋狂,並開始使圖像褪色。 找不到與此相關的任何內容,因此我至少想知道這是代碼問題還是軟件問題。

這是代碼(與jQuery一起使用):

$(function() {

    // slideshow
    var slideshow = {
        id : false,
        current : 0,
        count : 0,
        interval : false,
        init : function(data) {
            if (!data)
                return false;

            $.each(data, $.proxy(
                function(index, value) {
                    this[index] = data[index];
                }, this)
            );

            this.count = this.images.length;

            for (x=1;x<=this.count;x++)
                $('#slider ul.nav').append('<li></li>');

            $('#slider ul.nav li').live('click', function()
            {
                slideshow.click(this);
            });

            $('#slider ul.nav li:eq(0)').addClass('on');
            $('#slider ul.nav').css('width', (15*this.count)+'px');

            return true;
        },
        start : function () {
            slideshow.id = setInterval(function() { slideshow.action(); }, slideshow.options.interval);
        },
        stop : function() {
            clearInterval(slideshow.id);
        },
        action : function() {
            slideshow.current < (slideshow.count-1) ? slideshow.current++ : slideshow.current = 0;

            $('#slider img').fadeOut('normal', function() {
                $('#slider img').attr('src', slideshow.images[slideshow.current].url);
                $('#slider ul.nav li').removeClass('on');
                $('#slider ul.nav li:eq('+slideshow.current+')').addClass('on');
                $('#slider div.title').html(slideshow.images[slideshow.current].title);
                $('#slider div.description').html(slideshow.images[slideshow.current].description);
                $('#slider a.more').attr('href', slideshow.images[slideshow.current].target);
            }).fadeIn('normal');

            return true;
        },
        click : function(o) {
            slideshow.stop();

            var index = $('#slider ul.nav li').index(o);
            slideshow.current = index;

            $('#slider img').fadeOut('normal', function() {
                $('#slider img').attr('src', slideshow.images[index].url);
                $('#slider ul.nav li').removeClass('on');
                $(o).addClass('on');
                $('#slider div.title').html(slideshow.images[index].title);
                $('#slider div.description').html(slideshow.images[index].description);
                $('#slider a.more').attr('href', slideshow.images[index].target);
            }).fadeIn('normal');

            slideshow.start();
            return true;
        },
    };

    slideshow.init(slider);
    slideshow.start();

});

我寧願重復使用setTimeout()而不是使用setInterval()-setInterval()可能會出錯,並且您不知道瀏覽器的繁忙程度以及間隔是否現實。

瀏覽器不完全遵守您選擇的超時或間隔。 這主要是為了安全; 以防止大量事件干擾瀏覽器正常運行的能力。 Chrome可以更精確地兌現計時器,盡管它在后台顯示標簽時仍會大大降低計時器的速度(例如, 請參見此答案 )。

如果您在對slideshow.action()的現有調用期間使用setTimeout設置了一個新計時器,那么當您的瀏覽器無法完全跟上時您將不會排隊等待事件,但是當瀏覽器處於運行狀態時它仍將快速運行。能夠做到。

您仍然可以使用計時器ID停止計時器,該ID只會經常更改。

當選項卡在后台時,Chrome(顯然也是最新版本的Firefox)會降低setInterval的速度,以提高前台性能。 當后台頁面中有快速運行的計時器驅動的動畫時,這可能最重要。 當頁面回到前台時,它會“嘗試”以趕上並運行一堆setInterval調用,其速度比正常情況下快得多。

解決方法是:

  1. 延長setInterval的時間,以使Chrome不會弄亂它(您必須查明那是什么時間)。
  2. 當頁面進入后台時停止您的間隔計時器(當頁面始終不可見時無需運行幻燈片)-當頁面進入前台時再次啟動它。
  3. 使用重復的setTimeout代替setInterval並使用某種類型的重復的setTimeout,如下所示:

碼:

function nextSlide() {
    // show next slide now
    // set timer for the slide after this one
    setTimeout(function() {
        nextSlide();       // repeat
    }, xxx)
}

類似的帖子在這里

最有可能的是,您不應期望setInterval永遠是准確的。 如果我是您,則可以通過將前一個時間間隔與當前時間間隔進行比較來檢查該時間間隔是否正確。 那應該使代碼更健壯。

鉻也有類似的問題

由於我已經解決了這個問題。 首先,寫下mktime變量,然后簡單地從當前時間中減去。 例:

var values = {};

function mktime(){
 var date = new Date();
 return Math.floor(date.getTime()/1000);
}
function getTime(string){
  var splitContent = string.split(/\:/g);
  var hours = parseInt(splitContent[0]) * 60 * 60;
  var minutes = parseInt(splitContent[1]) * 60;
  var seconds = parseInt(splitContent[2]);                          
  return hours + minutes + seconds;
}
function startTimer(time){

 values.startMkTime = mktime();
 values.startTime = getTime(time);
 setInterval(process(),1000);                       
}

function process(){
   values.currentTime = (mktime() - values.startMkTime) +       o.values.startTime;//new code
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM