Cain Nuke
Cain Nuke

Reputation: 3079

setinterval working very randomly

Hi,

I have this code:

//<![CDATA[
$(window).load(function(){
setInterval(function(){ 
   // toggle the class every 10 seconds
   $('body').addClass('new');  
   setTimeout(function(){
     // toggle back after 10 seconds
     $('body').removeClass('new');  
   },10000)
},10000);
});//]]>

This code is supposed to add the class "new" to body 10 seconds later after the page first loads and then remove it after 10 seconds again to start all over going into an endless loop. But it wont work as expected. Sometimes it takes way longer than 10 seconds to add the class and it removes it too soon. Some other times it does it only once and then the loop ends just like that.

Whats wrong here? A more effective and reliable alternative will be also welcome.

Thank you.

Upvotes: 1

Views: 121

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074268

You've told the code adding the class to run every 10 seconds. Every 10 seconds, you also schedule a timer to remove the class 10 seconds later. So as of the 20th second, you have a race — will the first timer get there first, or will the second? In any case, it won't have the result you want.

Use a single timer that toggles:

setInterval(function() {
    $("body").toggleClass("new");
}, 10000);

As for it taking a long time to start, remember that the window load event doesn't occur until all resources have finished downloading, including all of your images and such. So the whole process may be starting quite a bit later than you expect.

Also note that browsers are increasingly "dialing back" timers in inactive tabs, so your timer may not be running, or may run infrequently, when the window it's in doesn't have focus.


From your comment:

But just as a bonus. What if I want to have the class to last 20 seconds but keep the interval in 10 seconds?

That complicates things. You could have a flag that you toggle, and only toggle the class when the flag is in one state or the other. E.g., something like:

(function() { // Scoping function so the flag isn't a global
    var flag = true;
    setInterval(function() {
        if (flag) {
            $("body").toggleClass("new");
        }
        flag = !flag;
    }, 10000);
})();

That will add the class at 10 seconds, toggle the flag at 20, remove the class at 30, toggle the class at 40, then start the cycle again. Adjust as needed.

Upvotes: 8

Related Questions