2011-08-05 1 views
9

웹 사이트에서 이름이 나타내는 일반적인 작업을 수행 할 수있는 맞춤식 슬라이드 쇼 객체가 있습니다. Chrome에서 탭을 전환하고 웹 사이트 탭으로 돌아가는 경우를 제외하면 모두 잘 작동합니다. 이런 일이 발생하면 슬라이드 쇼가 진행되어 주어진 setInterval 간격을 무시하고 이미지가 흐려지기 시작합니다. 이것과 관련된 anyhing을 찾을 수 없으므로 적어도 코드 또는 소프트웨어 문제에 문제가 있는지 알고 싶습니다.크롬에서 setInterval이 제대로 작동하지 않습니다.

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

}); 

답변

11

setInterval()을 사용하여 setTimeout()을 반복적으로 사용하는 것이 좋습니다. setInterval()을 사용하면 여러 가지 문제가 발생할 수 있으며 브라우저가 얼마나 바쁜지와 간격이 현실인지 여부를 알 수 없습니다.

브라우저는 선택한 시간 초과 또는 간격을 정확히 나타내지 않습니다. 이는 주로 보안을위한 것입니다. 이벤트의 홍수로 인해 브라우저 기능이 정상적으로 작동하지 않습니다. Chrome은 타이머가 더 정확하게 적용되는 것이 더 좋지만 탭이 백그라운드 (예 : see this answer)에있을 때 타이머를 크게 느리게 만듭니다.

기존의 slideshow.action() 호출 중에 setTimeout을 사용하여 새 타이머를 설정하면 브라우저가 제대로 작동하지 않을 때 대기 이벤트가 실행되지 않지만 계속 멋지고 빠르게 돌아갑니다. 브라우저가 그렇게 할 수있을 때.

타이머 ID를 사용하여 타이머를 중지 할 수 있습니다.이 ID는 자주 변경됩니다.

+0

성공하지 못한'setTimeout()'시도. Chrome 탭의 문제는 스크립트에 타임 스탬프의 차이를 지정하고 간격을 조정한다고해도 (console.log를 사용하면 변경되지 않았 음을 알 수 있습니다. Chrome에서 탭 처리가 멈추는 것으로 생각됩니다) . – yoda

+1

답변보기 : http://stackoverflow.com/questions/6032429/chrome-timeouts-interval-suspended-in-background-tabs/6032591#6032591 – thomasrutter

+0

고맙습니다. – yoda

2

대부분의 경우, 당신은 setInterval을 적 정확성을 기 대해서는 안 :

여기 (jQuery를 함께 사용) 코드입니다. 내가 너라면, 이전 간격 시간을 현재 간격과 비교하여 간격이 맞는지 확인해야합니다. 그러면 코드가 더욱 강력 해집니다.

8

Chrome (그리고 분명히 Firefox의 최신 버전이기도합니다)은 전경 성능을 향상시키기 위해 탭이 백그라운드에있을 때 setInterval의 속도를 줄입니다. 백그라운드 페이지에서 빠르게 실행되는 타이머 구동 애니메이션이있을 때 가장 중요합니다. 페이지가 포 그라운드로 돌아 오면, 정상적으로 실행하는 것보다 훨씬 더 빨리 setInterval 콜을 따라 잡으려고 "시도"합니다.

작업 차선책은 다음과 같습니다

  1. 길게 그것으로하여 setInterval 때문에 크롬의 시간을하지 않습니다 엉망 (그 시간이 무엇인지 찾아해야 할 것이다).
  2. 페이지가 백그라운드로 전환 될 때 인터벌 타이머를 중지하십시오. 어쨌든 슬라이드가 보이지 않을 때 슬라이드를 실행할 필요가 없습니다. 그런 다음 페이지가 포 그라운드로 오면 다시 시작하십시오.
  3. 사용은 다음과 같이 반복의 setTimeout의 몇 가지 유형으로 setTimeout 대신 setInterval 반복 :

코드 :

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

유사 포스트 here.

+0

흥미로운 ... – karim79

+2

작동하지 않았습니다. 크롬은 여전히 ​​어린 아이처럼 행동합니다. – yoda

0

크롬에서도 이와 비슷한 문제가 발생했습니다.

이 문제가 해결되면서. 처음에 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 
} 
+0

'setInterval (process(), ...)'는'process'의 반환 값을 실행하려고합니다. 이것은 거의 당신이 원하는 것이 아닙니다. 'setInterval'은 첫 번째 인수 (또는 문자열이지만 여기서는 중요하지 않음)로 함수 참조를 취합니다. –