0

Acknowledging that the setTimeout() method is asynchronous and therefore starting with this:

for (var i = 1; i <= 3; i++) {
  (function(i) {
    setTimeout(function() {
      console.log(i + " second(s) elapsed");
    }, i * 1000);
  })(i);
}

I'd like to replace console.log() with something to the effect of

  • window.open("https://www.twitter.com","_self") or document.getElementById("myFirstID").click();

  • and window.open("https://www.facebook.com","_self") or document.getElementById("mySecondID").click();,

called alternatingly, each with a delay of, say, 5 minutes, but need some help replacing it without breaking it :-) Therefore I ask.


This was one early (but unsuccessful) attempt:

i=0;
while(i < 100)
{
    setTimeout(function(){ window.open("https://www.bbc.com","_self") }, 3000);
    setTimeout(function(){ window.open("https://www.cnn.com","_self") }, 3000);
  i++
}

tldr;

also thought of using a switch() statement


See also:

How to make setTimeout in while loop execute sequentially in JavaScript?

JavaScript closure inside loops – simple practical example

Calling two methods alternately after every 5 minutes.

nutty about natty
  • 1,267
  • 2
  • 10
  • 17
  • `window.open()` requires a user event to occur in order to prevent abuse and have any web page open lots of windows – charlietfl May 14 '18 at 21:20
  • @charlietfl you mean, like a mouse click? -- either way: [it works](https://stackoverflow.com/q/50326060/2153622), or at least seems to... that is, I can call it via Firefox' Scratchpad... – nutty about natty May 14 '18 at 21:23
  • you are probably looking for `setInterval()` in this case – Calvin Nunes May 14 '18 at 21:24
  • @CalvinNunes like [here](https://stackoverflow.com/questions/32581261/how-to-make-settimeout-in-while-loop-execute-sequentially-in-javascript/32581414?noredirect=1#comment87672589_32581414). – nutty about natty May 14 '18 at 21:26
  • 1
    https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval – Pop-A-Stash May 14 '18 at 21:27
  • How/why should the second call to `window.open(..., '_self')` be executed, if the first one made you leave the page? Basically, questioning the whole concept with the loop. – Thomas May 14 '18 at 21:30
  • @Thomas 'cuz the script is to be run not from the site itself but "externally" (e.g. via Firefox' Scratchpad). – nutty about natty May 14 '18 at 21:34

3 Answers3

2

You can have two functions that call each other with a timeout, like so. You can also keep track of the timer, in case you want to stop it when an event occurs, or after a certain duration.

function toggleCalls () {
  var timer = {timeout: null};
  function callA () {
    console.log("A Called");
    timer.timeout = setTimeout(callB, 1000);
  }
  function callB () {
    console.log("B Called");
    timer.timeout = setTimeout(callA, 1000);
  }
  callA();
  return timer;
}

var timer = toggleCalls();

setTimeout(function () {
  clearTimeout(timer.timeout);
  console.log("stopped");
}, 5000);
mhodges
  • 10,938
  • 2
  • 28
  • 46
  • Tried replacing `console.log("A Called");` with `window.open("https://www.twitter.com","_self")`, etc, but that calls only site A (e.g. twitter.com) and stays there; site B is never loaded. Can your script work with `window.open()` at all or would it only work with the other method `document.getElementById("myFirstID").click();` (which I have yet to try) ? – nutty about natty May 15 '18 at 07:24
  • @nuttyaboutnatty As others have mentioned, you cannot do a `window.open()` programmatically to open sites in a different domain to prevent websites from spam-opening sites, or opening a domain you don't intend to go to. You can try the `.click()`, that will likely work – mhodges May 15 '18 at 15:03
  • Will try. The thing I find irritating though is that `window.open()` seems to be blocked "silently"; can't find a mention of it in the browser log or elsewhere (yet). – nutty about natty May 15 '18 at 15:27
  • 1
    @nuttyaboutnatty From the [FAQ section on MDN about Window.open](https://developer.mozilla.org/en-US/docs/Web/API/Window/open#FAQ): "**How can I tell when my window was blocked by a popup blocker?** *With the built-in popup blockers of Mozilla/Firefox and Internet Explorer 6 SP2, you have to check the return value of window.open(): it will be null if the window wasn't allowed to open. However, for most other popup blockers, there is no reliable way.*" – mhodges May 15 '18 at 16:23
  • With `click()` it goes one step further (than with `window.open()`) in that it opens site A followed by site B but then just sits there and stops (at site B). So both A and B are called just once; what I'd like to see is them called, say, 1000x times. Is that sth that can be fixed? – nutty about natty May 16 '18 at 15:46
1

If you want to go in a loop you can put the urls in an array and loop over them, calling setTimeout() for the next one each time:

let urls = [
    "https://www.bbc.com",
    "https://www.cnn.com",
    "https://www.npr.org"
]
function openURLs(urls, i=0){
    setTimeout(function(){
         console.log(urls[i]) // or whatever you want to call here
         openURLs(urls, (i+1) % urls.length)
        }, 1000)
}
openURLs(urls)

Further notes:

Remainder % (aka "modulo")

alert(1 % 3); // 1
alert(2 % 3); // 2
alert(3 % 3); // 0

alert(4 % 3); // 1
nutty about natty
  • 1,267
  • 2
  • 10
  • 17
Mark
  • 90,562
  • 7
  • 108
  • 148
  • 1
    I almost posted this as an alternative to the other method I posted, but you beat me to it. This is a good way to do it. You can also have an array of functions if more work needs to be done than just opening a url. `[openBBC, openCNN, openNPR, ...]` and call those with `urls[(i+1)%urls.length]()` – mhodges May 14 '18 at 21:35
  • hmm; copy-pasted to Firefox Scratchpad; hit-(and)-run; no dice. – nutty about natty May 14 '18 at 21:39
  • @nuttyaboutnatty I just ran it in scratchpad without issue. `console.log()` gets written to the console in the browser window — so you need to loo there for output. But you're probably going to do something other than just log to the console. – Mark May 14 '18 at 21:50
  • thanks for your answer and for running it: I need to figure out why it's not (yet) working on my system. dunno yet why (the browser console throws some error but not sure if it's originating from running this script or another open website) but when I do I'll report back :) – nutty about natty May 14 '18 at 21:54
  • Managed to get it to run in 2 out of 3 FF browsers (still can't figure out why it won't run in 1 of them). Could you perhaps explain how to replace `console.log()` with `window.open()` and/or `document.getElementById("mySecondID").click();`? Many thanks! – nutty about natty May 15 '18 at 07:19
  • Plus, may I kindly ask you to add a few explanatory comments around the two lines within `setTimeout()`? Thanks! – nutty about natty May 15 '18 at 19:46
  • Managed to insert the `click()` element: it clicks once and stops: the loop runs just once. Is this fixable? – nutty about natty May 16 '18 at 15:11
0

Try to use Interval function.

  setInterval (()=> {
     // TODO inserte code here
    }, 300*1000);   
Abel Valdez
  • 2,368
  • 1
  • 16
  • 33