3

So, I want to put delay on this JavaScript code.

$(function(){ 
     $('.clickThis').each(function(){ 
         $(this).click();
     }); 
});

I tried this

$(function(){ 
     $('.clickThis').each(function(){
         $(this).click().delay(5000); 
     }); 
});

above script doesnt work .

Is there any alternative?

I've tried Google it but I still couldn't figure it out, because I have little knowledge in JavaScript.

Ja͢ck
  • 170,779
  • 38
  • 263
  • 309
user2054689
  • 25
  • 1
  • 3
  • Docs are your friends. `The .delay() method is best for delaying between queued jQuery effects. Because it is limited—it doesn't, for example, offer a way to cancel the delay—.delay() is not a replacement for JavaScript's native setTimeout function, which may be more appropriate for certain use cases.` http://api.jquery.com/delay/ – mrtsherman Feb 08 '13 at 14:47

7 Answers7

9

This will do it:

$(function(){ 
    $('.clickThis').each(function(i, that){ 
        setTimeout(function(){
            $(that).click();
        }, 5000*i );
    }); 
});
Cerbrus
  • 70,800
  • 18
  • 132
  • 147
Gabriele Petrioli
  • 191,379
  • 34
  • 261
  • 317
  • except that if there are more than one .clickthis, the second one won't wait for the first one to be triggered to start waiting 5sec before being triggered – mikakun Feb 08 '13 at 14:52
  • @mikakun there's no need to wait - this code will attempt to trigger each click 5 seconds apart, not 5 seconds from "completion" of the previous click. Your own code does the same – Alnitak Feb 08 '13 at 14:54
  • @Ainitak yeah ok didn't see the `*i` at first look; why not (would still use my solution though seems better semantic than have all those timeout going on at the same time) – mikakun Feb 08 '13 at 14:55
  • 2
    @mikakun don't take this the wrong way, but I wouldn't use your code. It's far less clear than this version. It's messy too. – Alnitak Feb 08 '13 at 14:56
  • @Alnitak my code makes only one access to the dom whatever the number of item; here you have one access at every item + the initial $(".clickthis') + nothing is cached – mikakun Feb 08 '13 at 14:59
  • @mikakun no, this version does exactly the same DOM access as yours. If there is a valid criticism of this solution it's that it schedules `n` timers all in one go, but using `setInterval` isn't the right way to fix that - it would be to start the next timer each time through the loop. Roger's answer links to that, but there's no up votes just for linking to someone else's blog. – Alnitak Feb 08 '13 at 15:02
  • wrong `$(that)` is extra job compare to `eq(i)` or `[i]` on a cached object; & please expand on why using setInterval is bad compare to looping timeout... i'm curious – mikakun Feb 08 '13 at 15:15
  • @mikakun both `$(that)` and `.eq(i)` create a new jQuery object and have the same cost, but neither will require any DOM access. `[i]` is just wrong, because that's the DOM element, not a jQuery object. `setInterval` is potentially dangerous because it can result in multiple events all firing immediately after the other, whereas calling `setTimeout` in each iteration guarantees that each iteration _cannot_ start until 5s after the last one finished. – Alnitak Feb 08 '13 at 15:21
5

Here's a version using a recursive setTimeout loop.

$(function() {
    var click = $('.clickThis').toArray();

    (function next() {
        $(click.shift()).click();   // take (and click) the first entry
        if (click.length) {         // and if there's more, do it again (later)
            setTimeout(next, 5000);
        }
    })();
});

The advantage of this pattern over setTimeout(..., 5000 * i) or a setInterval call is that only a single timer event is ever queued at once.

In general, repeated calls to setTimeout are better than a single call to setInterval for a few reasons:

  1. setInterval calls can queue up multiple events even if the browser isn't active, which then all fire as quickly as possibly when the browser becomes active again. Calling setTimeout recursively guarantees that the minimum time interval between events is honoured.
  2. With setInterval you have to remember the timer handle so you can clear it
Alnitak
  • 334,560
  • 70
  • 407
  • 495
0

Try to use this:

$(function () {
    var items=$('.clickThis');
    var length=items.length;
    var i=0;
    var clickInterval=setInterval(function(){
        items.eq(i).click();
        i++;
        if(i==length)
            clearInterval(clickInterval);
    }, 5000);
});
Ruslan Polutsygan
  • 4,401
  • 2
  • 26
  • 37
0

You need to write an asynchronous setTimeout loop, for more information http://www.erichynds.com/javascript/a-recursive-settimeout-pattern/

Roger C
  • 338
  • 1
  • 5
0
var $clickthis=$(".clickthis");
var i= -1;
var delayed = setInterval(function(){
 if (++i < $clickthis.length) $clickthis.eq(i).trigger("click");
 else clearInterval(delayed);
}, 5000);
mikakun
  • 2,203
  • 2
  • 16
  • 24
-1

I am not sure but I think that setTimeout function should do the trick. See here https://developer.mozilla.org/en-US/docs/DOM/window.setTimeout

Mickael
  • 5,711
  • 2
  • 26
  • 22
  • Generally answers should only link out to third party resources to support the answer. You shouldn't use them as your actual answer. I know it is tempting as getting answers in fast enough is pretty hard on SO. (PS I didnt downvote). – mrtsherman Feb 08 '13 at 14:53
  • I down voted. Firstly, because of the reason mrtsherman gave. Secondly, because you posted a link without actually knowing whether it would help. Answers are supposed to be definitive, not "guesses". – Alnitak Feb 08 '13 at 14:57
  • Sorry, I thought this documentation was the best explanation. I will take time to give a better answer the next time. – Mickael Feb 08 '13 at 15:01
  • Thank you for the link, the top answer is also using setTimeout. I wish your link would help me to figure out how the top answer's work . – user2054689 Feb 08 '13 at 15:47
  • @user2054689 the top answer works simply because `.each()` calls the supplied function with the index of the current element, so you end up with `n` timers each starting at `5000 * i`. – Alnitak Feb 08 '13 at 19:37
-3

Try

$(function(){ 
     $('.clickThis').each(function(_,i){ 
        var me=$(this);
        setTimeout(function(){me.click()},5000*i);
     ); 
});
dlock
  • 9,447
  • 9
  • 47
  • 67
  • this fires all the click events in one go, not 5s apart. – Alnitak Feb 08 '13 at 15:33
  • He didn't mention that he want them to fire one by one. If that's the case, he could just multiply the loop index by the interval. – dlock Feb 08 '13 at 15:37
  • he did say "in each iteration", and multiplying by the loop index is what the current top answer does (even though that answer actually has a bug in it). – Alnitak Feb 08 '13 at 15:40
  • Where did he say "in each iteration"? I can't see that in his question content. Maybe he styled it with `display:none` ? :) – dlock Feb 08 '13 at 15:47
  • Well deadlock, thanks for the answer. Sory, I forgot to mention what Alnitak said. I want the click event work one by one . – user2054689 Feb 08 '13 at 15:50
  • @deadlock it's in the question subject. – Alnitak Feb 08 '13 at 19:38