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.

7
  • window.open() requires a user event to occur in order to prevent abuse and have any web page open lots of windows Commented May 14, 2018 at 21:20
  • @charlietfl you mean, like a mouse click? -- either way: it works, or at least seems to... that is, I can call it via Firefox' Scratchpad... Commented May 14, 2018 at 21:23
  • you are probably looking for setInterval() in this case Commented May 14, 2018 at 21:24
  • @CalvinNunes like here. Commented May 14, 2018 at 21:26
  • 1
    developer.mozilla.org/en-US/docs/Web/API/… Commented May 14, 2018 at 21:27

3 Answers 3

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);

Sign up to request clarification or add additional context in comments.

5 Comments

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) ?
@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
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).
@nuttyaboutnatty From the FAQ section on MDN about Window.open: "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."
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?
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

7 Comments

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]()
hmm; copy-pasted to Firefox Scratchpad; hit-(and)-run; no dice.
@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.
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 :)
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!
|
0

Try to use Interval function.

  setInterval (()=> {
     // TODO inserte code here
    }, 300*1000);   

Comments

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.