Search code examples
javascriptfirefoxpopuptimeout

Why is window.open() silently ignored iff called from within a loop and via setTimeout()?


--- EDIT.

I don't get it; yesterday it seemed to be ignored; now it seems to be working. Even within loop and called via setTimeout(). Currently I seem to be having difficulties replicating yesterday's behaviour... What is going on?


--- 2nd EDIT.

First idea how to "fix" the replication of the issue: weirdly, whether or not this works seems to be dependent on the current URL! E.g. works from SE-sites, but not from, say, http://www.asdf.com/. How so?


Whereas setTimeout() works here:

setTimeout(function(){ alert("Hello"); }, 3000);

and window.open() works here:

window.open("https://www.bbc.com","_self");

and even the combination of the two works here:

setTimeout(function(){ window.open("https://www.bbc.com","_self") }, 3000);

suddently and unexpectedly the combination of the two is - silently - ignored in a loop:

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

Why?


tldr;

This question seems to have come up close to a million times already but not yet (as far as I could tell / search) with a succinct Q&A format; e.g.

Settimeout() javascript function is ignored

Simulating JavaScript's setTimeout() method “from first principles”


Solution

  • Popup blockers in most popular browsers will only allow a new window to be opened if it is opened as a result of code running from a direct user action such as a click. Because a setTimeout() happens some time in the future, is not considered the direct result of a user action so attempts to open windows from setTimeout() are likely blocked by the popup blocker.

    In essence, trying to fire window.open from within setTimeout() leaves the browser to "think" it's a popup which deserves (silent) blocking. -- If, in contrast, window.open is fired on it's own, the browser seems to treat it like a "user click", that is, not as spam to be blocked.