0

I am using the following function on a website. Excusing the sloppy jQuery I'm using, is there any way to run this function multiple times without declaring it as a standalone function and without copying and pasting the code several times?

Exhibit A:

setTimeout(function(){

    $('.nav > li > a').each(function(k,el){
        var width = $(this).parent().width();
        $(this).next('span').width(width);
    });

},1000);

I don't want to do this:

setTimeout(function(){
        // same code here   
},1000);

setTimeout(function(){
        // same code here   
},3000);

setTimeout(function(){
        // same code here   
},5000);

Nor do I want to do this:

function myfunction{
    // same code here   
}

setTimeout('myFunction()',1000);
setTimeout('myFunction()',3000);
setTimeout('myFunction()',5000);
1
  • Are you wanting it to call itself at the end in a setTimeout (basically run every X seconds) or just n different calls to setTimeout with the same function? Commented Dec 13, 2011 at 19:47

4 Answers 4

3
for (var i = 1000; i <= 5000; i += 2000) {
    setTimeout(func, i);
}

or

var times = [1000, 3000, 5000];
for (var i=0; i<times.length; i++) {
    setTimeout(func, times[i]);
}

newer browsers only

[1000, 3000, 5000].forEach(function(time){
    setTimeout(func, time);
});
Sign up to request clarification or add additional context in comments.

3 Comments

nice use of the mapping with native js
+1 I didn't know about forEach. That's a good one and I will use that. I just check in firefox and works, will check all major browser and if that is part of them, this is a pretty awesome thing you just showed me in terms of ease of use.
IE8 doesn't support it. Wouldn't you know IE would be the dummy of the group. Hope IE9 does. Let me know as I have a mac. Thanks.
3

Yes, use the setInterval method.

setInterval(function() {
    $('.nav > li > a').each(function(k,el){
      var width = $(this).parent().width();
      $(this).next('span').width(width);
    }); 
}, 2000);

//run every two seconds

Alternatively, you can call setTimeout repeatedly...

myFun = function() {
    $('.nav > li > a').each(function(k,el){
      var width = $(this).parent().width();
      $(this).next('span').width(width);
    });
    setTimeout(myFun, 2000);
}

setTimeout(myFun,1000);

This should have the same effect as doing 1000,3000,etc...

2 Comments

how can i make it stop after 10 seconds?
If you use setInterval, you can use clearInterval. Or, if you must count from 1,3, etc, you can have a variable for your time elapsed and not call the final setTimeout if greater than 10 secs.
1

You could use $.map

$.map([1000,3000,5000], function(time,index){ 

 setTimeout(function(){
        $('.nav > li > a').each(function(k,el){
        var width = $(this).parent().width();
        $(this).next('span').width(width);
    });
 },time);

}); 

2 Comments

actually it's not quite working. the mapping loop works, but only one setTimeout is set.
It should, i had the time and index values mixed up before.
1
(function(){
    var i, weirdProblem = function(timeout) {
        setTimeout(function() {
            $('.nav > li > a').each(function(){
                var width = $(this).parent().width();
                $(this).next('span').width(width);
            });
        },timeout);
    };
    for(i = 1; i <= 5; i+=2) {
        weirdProblem(i*1000);
    }
})();

The closure encapsulates the declarations and will be garbage collected once no longer used. Not sure the point of this though. Very strange.

5 Comments

looks good. +1. this i'm resizing nav menu items after the nav fonts have been rendered using typekit - therefore a timeout is needed, multiple in case the user has a slow connection ;)
Google fonts are better to use, trust me. There is no refresh that happens. I loath typekit but I understand it does have many more standard fonts that designers look for. Just got to take the refresh as part of it. :)
actually i have been fairly happy with the performance of typekit and i believe the fonts are cached which improves the loadtime. the problem i'm solving is doing a tricky overlay with some dropdown menus, and the problem is the time between when $(document).ready occurs and when the fonts are rendered. i actually can't see it when watching the page load, but the values of $(el).width() are in fact different if you wait a fraction of a second :) thanks again for your answer.
i did klim.com with typekit per the client's request. there is a lot of jquery going on there if you check that one out
typekit should have a javascript api you can use to know when it loaded, the set timeout thing is not reliable, its better to use the api to know when things are loaded, you should revisit this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.