0

I would like to simply set a delay between each click. Shown below is the script I created. It works fine with clicking each element the way I want it to. The problem is that it clicks each element almost at the same time causing me horrible lag.

Original Code.

var timerVar = setInterval (function() {DoMeEverySecond (); }, 5000); // 
<< set to 2 seconds.

function DoMeEverySecond ()
{
(function() {
document.getElementsByName("zTab")[0].click();
document.getElementsByName("zButton")[0].click();
document.getElementsByName("zClose")[0].click();
})();
}

Would it be possible to do something like this.

var timerVar = setInterval (function() {DoMeEverySecond (); }, 5000); // 
<< set to 2 seconds.

function DoMeEverySecond ()
{
(function() {
document.getElementsByName("zTab")[0].click();
-----------A DELAY HERE!-----------
document.getElementsByName("zButton")[0].click();
---------- ANOTHER ONE HERE! ----------------
document.getElementsByName("zClose")[0].click();
})();
}

The code is very simple, I tried to explain it as best as I could. Could someone help me out on this piece of code

  • In general, that is a very brittle and fiddly way to do things. Better to use [a different approach](https://stackoverflow.com/questions/15048223/choosing-and-activating-the-right-controls-on-an-ajax-driven-site). – Brock Adams May 05 '19 at 20:26

2 Answers2

1

Here's a live demo of a potential solution. See the inline comments:

// Lets just add some logging here for when the buttons are clicked
document.querySelectorAll('.z-tab').forEach(element => {            
  element.addEventListener('click', e => console.log('Z Tab'));
});

document.querySelectorAll('.z-button').forEach(element => {            
  element.addEventListener('click', e => console.log('Z Button'));
});

document.querySelectorAll('.z-close').forEach(element => {            
  element.addEventListener('click', e => console.log('Z Close'));
});

// Let's take advantage of async/await 
async function DoMeEverySecond () {
  const elementClassNames = ['.z-tab', '.z-button', '.z-close'];

  for (let i = 0; i < elementClassNames.length; i++) {
    const element = document.querySelectorAll(elementClassNames[i])[0];
    await delayFor(1000); // Let's wait 1000ms between each click
    element.click()
  }
}

// Delay function that will resolve a promise after the setTimeout delay has been passed.
function delayFor(delay) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve();
    }, delay);
  });
}
DoMeEverySecond ();
<h2>Z Tabs</h2>
<button class="z-tab">1</button> <button class="z-tab">2</button>

<h2>Z Buttons</h2>
<button class="z-button">1</button> <button class="z-button">2</button>

<h2>Z Close</h2>
<button class="z-close">1</button> <button class="z-close">2</button>
Brock Adams
  • 86,878
  • 22
  • 220
  • 282
James Hall
  • 26
  • 4
  • Note that the previous stackblitz demo (A) is no longer needed and (B) trips errors in my browser when clicking the buttons. – Brock Adams May 05 '19 at 20:20
  • Also, this answer currently is using `class`, but the OP requires the `name` attribute be used (and can't change the target HTML because it's a Tampermonkey scenario). – Brock Adams May 05 '19 at 20:22
1

Shure you can add delays, but as @Brock Adams mentioned, better use a different approach, like a promise-chain, to be shure all clicks were triggered, before looping again.

I assume a delay of 1 second, you can change this, but be aware, that if you add a delay in total of more that 5 seconds, the click-actins will overlap per interval.

So your code with delays:

function doMeInInterval () {
  document.querySelector("[name=zTab]").click();
  setTimeout(function() {
    document.querySelector("[name=zButton]").click();
    setTimeout(function() {
      document.querySelector("[name=zClose]").click();
    }, 1000);
  }, 1000);
}
var timerVar = setInterval(doMeInInterval, 5000);