3

I have a slideshow component that I wrote in javascript using jQuery. The slideshow consists of three slides, each containing HTML content. Each slide is a div with class .slide. Every 7 seconds, I fade out the slides that should be hidden and fade in the one I want to show. I also have some buttons (indicators) that let the user manually switch slides by clicking the buttons.

It all works great, unless the user switches tabs. If enough time elapses, when the user returns, there will be two slides visible. When the switch slide event fires, everything goes back to normal.

Example:

http://jsfiddle.net/vwdJ5/

Here is my code:

    var slides = $(".slide");
    var indicators = $(".indicator li");
    var currentSlide = 1;

    var incrementSlide = function () {
        currentSlide = currentSlide === 2 ? 0 : currentSlide + 1;
    };

    var switchSlide = function () {
        if (currentSlide === 0) {
            var onDeck = 1;
            var inTheHole = 2;
        } else if (currentSlide === 1) {
            var onDeck = 2;
            var inTheHole = 0;
        } else {
            var onDeck = 0;
            var inTheHole = 1;
        }

        indicators.removeClass("active");

        $(indicators[currentSlide]).addClass("active");

        $(slides[onDeck]).hide();

        $(slides[inTheHole]).fadeOut(200, function () {
            $(slides[currentSlide]).fadeIn(200);
            incrementSlide();
        });
    };

    var interval = setInterval(switchSlide, 7000);

    indicators.click(function () {
        clearInterval(interval);

        if ($(this).hasClass("first")) {
            currentSlide = 0;
        } else if ($(this).hasClass("second")) {
            currentSlide = 1;
        } else if ($(this).hasClass("third")) {
            currentSlide = 2;
        }

        switchSlide();
        interval = setInterval(switchSlide, 7000);
    });
Adam
  • 12,236
  • 9
  • 39
  • 44
  • In what browser does this happen and do you have an example somewhere? – Jasper Kennis Aug 26 '11 at 23:18
  • Chrome - I will make a jsFiddle with an example – Adam Aug 26 '11 at 23:18
  • Thanks. If I can look at it it's easier to say something about it, and the problem might also be in the html. – Jasper Kennis Aug 26 '11 at 23:22
  • http://jsfiddle.net/vwdJ5/ - I don't think it's the HTML, since, as you can see in the example, it happens even when the content is really simple. – Adam Aug 26 '11 at 23:27
  • I had a similar problem, check it out : http://stackoverflow.com/questions/6951727/setinterval-not-working-properly-on-chrome – yoda Aug 27 '11 at 04:21

1 Answers1

2

Modern browsers (Chrome and FF6 for sure) are now using a "queue" system on inactive tabs. You switch tabs, and setTimeout and setInterval still run, but at a much slower speed. Then when you go back to the tab, it tries to catch up, normally resulting in weird issues (sorry, probably not the most technical description).

It's recommended to use requestAnimationFrame instead if possible.

For your example where you need something to happen at specific times, you can just add stop() prior to the animations, which will prevent multiple animations from occurring at once

dc-
  • 1,878
  • 1
  • 15
  • 15
  • But requestAnimationFrame tries to animate at 60 FPS. That's definitely not what I want. – Adam Aug 27 '11 at 00:07
  • Ah that is true. You should be able to use stop() before your animations then. This will prevent having multiple animations at once, which is what is happening when a user comes back and the browser tries to catch up the the queue. I'll update the answer with a fiddle. – dc- Aug 27 '11 at 04:12
  • Using stop seems to do the trick. That was a weird bug - thanks for your help. – Adam Aug 29 '11 at 16:13