Elias Prado
Elias Prado

Reputation: 1817

How to loop a function in javascript

I have four different button effects where each effect are declared in a variable.

Therefore, I bring all of these four variables and place them within an array called arr in which is used in the clickByItself() function using Math.floor(Math.random()) methods.

Without the for loop, the code clicks by itself randomly in one of the four buttons every time I reload the page.

function clickByItself() {
   let random = Math.floor(Math.random() * arr.length);
   $(arr[random]).click();
}

However, using the for loop I am not being able to make these clicks one-by-one within the maximum of 10 times.

var blueButtonEffect = code effect here;
var redButtonEffect = code effect here;
var greenButtonEffect = code effect here;
var yellowButtonEffect = code effect here;
var arr = [blueButtonEffect, redButtonEffect, greenButtonEffect, yellowButtonEffect];

//will click on buttons randomly
function clickByItself() {
    let random = Math.floor(Math.random() * arr.length)
    var i;
    for (i = 0; i < 10; i++) {
        $(arr[random]).click();
        setTimeout(clickByItself(), 1000);
    }
}

The final output with the current code above is the four buttons being clicked at the same time, not one-by-one.

So, how can I have this function to press a random button by 10 times one-by-one with one second of interval from each click?

Upvotes: 2

Views: 170

Answers (3)

Alberto Rivera
Alberto Rivera

Reputation: 3752

To fix your code you need:

  1. A base case for your recursion
  2. Pass a function reference to setTimeout. Currently, you are executing clickByItself and passing its return value (which is undefined) to setTimeout.
  3. Do not use setTimeout in a loop without increasing the time by a factor of i, as the for loop will queue all the function calls at the same time
  4. Alternatively, you can use a "times" argument to avoid looping

You could try something like

function clickByItself(times = 0) {
  let random = Math.floor(Math.random() * arr.length)
  $(arr[random]).click();
  if (++times < 10) {
    setTimeout(function(){clickByItself(times);}, 1000);
  }
}

An example with console logs https://jsfiddle.net/pfsrLwh3/

Upvotes: 3

Pawan lakhera
Pawan lakhera

Reputation: 197

Are you saying this is working for only 4 times but I think your above code will run in an infinite loop as you are calling clickByItself() again in the for loop.

If you want press a random button by 10 times one-by-one with one second of interval from each click then replace the for loop with

for (i = 0; i < 10; i++) {
      setTimeout($(arr[random]).click(), 1000);
    }

Upvotes: 0

carter
carter

Reputation: 5432

The problem is that the for loop calls the setTimeout 10 times very quickly. If you want to wait until the previous function call finishes prior to calling the next, then you should use recursion or just use a setInterval.

Recursion:

function clickByItself(numIterations) {
    let random = Math.floor(Math.random() * arr.length)
    let i;

    $(arr[random]).click();

    if( numIterations < 10 ){
        setTimeout(() => {
            clickByItself(numIterations += 1)
        }, 1000) 
  }      
}

clickByItself(0);

With setInterval

let numIterations = 0;

function clickByItself() {
    let random = Math.floor(Math.random() * arr.length);
    let i;
    $(arr[random]).click();

    numIterations += 1;

    if( numIterations > 10) {
        clearInterval(loop)
    }
}

let loop = setInterval(test2, 1000);

Upvotes: 0

Related Questions