We ran across this same problem and hunted around SO for an answer. What we found works in our circumstances and the distilled wisdom is as follows:

The problem is related to browser pop-up blockers preventing programmatic window opens. Browsers allow window opens from actual user clicks which occur on the main thread. Similarly, if you call window.open on the main thread it will work, as noted above. According to this answer on Open a URL in a new tab (and not a new window) using JavaScript if you are using an Ajax call and want to open the window on success you need to set async: false which works because that will keep everything on the main thread.

We couldn't control our Ajax call like that, but found another solution that works because of the same reasons. Warning, it is a bit hacky and may not be appropriate for you given your constraints. Courtesy of a comment on a different answer on Open a URL in a new tab (and not a new window) using JavaScript you open the window before calling setTimeout and then update it in the delayed function. There are a couple of ways of doing this. Either keep a reference to the window when you open it, w = window.open... and set w.location or open with a target, window.open('', 'target_name'), in the delayed function open in that target, window.open('your-url', 'target_name'), and rely on the browser keeping the reference.

Of course, if the user has their settings to open links in a new window this isn't going to change that, but that wasn't a problem for the OP.

Answer from Yogh on Stack Overflow
Top answer
1 of 5
20

We ran across this same problem and hunted around SO for an answer. What we found works in our circumstances and the distilled wisdom is as follows:

The problem is related to browser pop-up blockers preventing programmatic window opens. Browsers allow window opens from actual user clicks which occur on the main thread. Similarly, if you call window.open on the main thread it will work, as noted above. According to this answer on Open a URL in a new tab (and not a new window) using JavaScript if you are using an Ajax call and want to open the window on success you need to set async: false which works because that will keep everything on the main thread.

We couldn't control our Ajax call like that, but found another solution that works because of the same reasons. Warning, it is a bit hacky and may not be appropriate for you given your constraints. Courtesy of a comment on a different answer on Open a URL in a new tab (and not a new window) using JavaScript you open the window before calling setTimeout and then update it in the delayed function. There are a couple of ways of doing this. Either keep a reference to the window when you open it, w = window.open... and set w.location or open with a target, window.open('', 'target_name'), in the delayed function open in that target, window.open('your-url', 'target_name'), and rely on the browser keeping the reference.

Of course, if the user has their settings to open links in a new window this isn't going to change that, but that wasn't a problem for the OP.

2 of 5
8

Like the other posts mentions the best way to do this is to first open the window and then set its location after the callback or asynchronous function

<input type="button" value="Open" onclick="cb1()">

<script type="text/javascript">

function cb1() {
  var w = window.open('', 'w2');
  setTimeout(function () {
    wo(w);
  }, 1000); //simple async
}

function wo(w)
{
  w.location = "http://google.com";
  w.focus();
}
</script>

Alternatively if you are using async await you will also have the same problem. The same solution still applies.

public async openWindow(): Promise<void> {
    const w = window.open('', '_blank');
    const url = await getUrlAsync();
    w.location = url;    
}

A further enhancement is to open the window on an initial page that provides some quick feedback either by loading a url or writing some html to that page

public async openWindow(): Promise<void> {
    const w = window.open('', '_blank');
    w.document.write("<html><head></head><body>Please wait while we redirect you</body></html>");
    w.document.close();
    const url = await getUrlAsync();
    w.location = url;    
}

This will prevent a user looking at a blank tab/window for however long it takes to resolve your URL.

Discussions

Javascript Window opener and callback
Find answers to Javascript Window opener and callback from the expert community at Experts Exchange More on experts-exchange.com
๐ŸŒ experts-exchange.com
October 31, 2003
Window.open callback returns undefined for new window
nw.Window.open('https://github.com', {}, function(new_win) { console.log(new_win); }); ยท new_win is randomly undefined. So if you run the code lets say 5 times. You might get undefined 2 times More on github.com
๐ŸŒ github.com
25
January 8, 2016
Return a value from window.open - javascript
We recently discovered that Chrome no longer supports window.showModalDialog which is problematic because our enterprise application uses this method. There is, apparently, a short term workaround... More on stackoverflow.com
๐ŸŒ stackoverflow.com
javascript - Callback function call when child window is close
I have open child window when click on button.In this window I have save some data into database. I want to call another java script function when child window is close. I have already tried this ... More on stackoverflow.com
๐ŸŒ stackoverflow.com
๐ŸŒ
MDN Web Docs
developer.mozilla.org โ€บ en-US โ€บ docs โ€บ Web โ€บ API โ€บ Window โ€บ open
Window: open() method - Web APIs | MDN
The open() method of the Window interface loads a specified resource into a new or existing browsing context (that is, a tab, a window, or an iframe) under a specified name. js ยท open() open(url) open(url, target) open(url, target, windowFeatures) url Optional ยท
๐ŸŒ
Experts Exchange
experts-exchange.com โ€บ questions โ€บ 20783665 โ€บ Javascript-Window-opener-and-callback.html
Solved: Javascript Window opener and callback | Experts Exchange
October 31, 2003 - NetGroove, I run XP Pro and when I try it in Netscape 7.1 and IE 6.0, clicking links on the Menu window seem to work ok but clicking back to the menu sometimes creates a new window (I am having a hard time detecting a pattern in this behaviour). Rob :) ... function openContentWindow (pageUrl) { var win = null; alert ("window.contentWindow = " + window.contentWindow.lengt
๐ŸŒ
GitHub
github.com โ€บ nwjs โ€บ nw.js โ€บ issues โ€บ 4188
Window.open callback returns undefined for new window ยท Issue #4188 ยท nwjs/nw.js
January 8, 2016 - nw.Window.open('https://github.com', {}, function(new_win) { console.log(new_win); }); ยท new_win is randomly undefined. So if you run the code lets say 5 times. You might get undefined 2 times
Author ย  eemi2010
Top answer
1 of 1
37

I have two ideas that could help you but the first one is tied to CORS, so you won't be able to use it from different domains at least you can access both services and configure them.

FIRST IDEA:

The first one is related to this native api. You could create on the parent window a global function like this:

window.callback = function (result) {
    //Code
}

As you can see it receives a result argument which can hold the boolean value you need. The you could open the popup using the same old window.open(url) function. The popup's onlick event handler could look like this:

function() {
    //Do whatever you want.
    window.opener.callback(true); //or false
}

SECOND IDEA: Solves the problem

The other idea I got is to use this other native api to trigger an event on the parent window when the popup resolves (better known as cross-document messaging). So you could do this from the parent window:

window.onmessage = function (e) {
    if (e.data) {
        //Code for true
    } else {
        //Code for false
    }
};

By this way you are listening to any posted message on this window, and checking if the data attached to the message is true (the user clicks ok in the popup) or false (the user clicks cancel in the popup).

In the popup you should post a message to the parent window attaching a true or a false value when corresponds:

window.opener.postMessage(true, '*'); //or false

I think that this solution perfectly fits your needs.

EDIT I have wrote that the second solution was also tied to CORS but digging deeper I realized that cross-document messaging isn't tied to CORS

๐ŸŒ
SysTutorials
systutorials.com โ€บ home โ€บ systutorials posts โ€บ how to capture the close event of an opened window by window.open() in javascript?
How to capture the close event of an opened window by window.open() in JavaScript? - SysTutorials
March 24, 2018 - var newwindow = window.open("/newwindow.html"); newwindow.onbeforeunload = function () { // processing event here alert("new window closed"); } Note that after the callback function is executed, the newwindow is closed.
Find elsewhere
Top answer
1 of 2
5

HTML5's postMessage comes to mind. It's designed to do exactly what you're trying to accomplish: post messages from one window and process it in another.

https://developer.mozilla.org/en/DOM/window.postMessage

The caveat is that it's a relatively new standard, so older browsers may not support this functionality.

http://caniuse.com/#feat=x-doc-messaging


It's pretty simple to use:

To send a message from the source window:

window.postMessage("message", "*");
//'*' is the target origin, and should be specified for security

To listen for messages in a target window:

window.addEventListener
("message", function(e) {
console.log(e.data); //e.data is the string message that was sent.
}, true);
2 of 2
1

After few more hours of experiments, I think, I've found a viable solution for my problem.

The point is to reference jQuery from parent window and trigger a jQuery event on this window (I'm a Mac user but I suppose, jQuery has events working cross-platform, so IE compatibility is not an issue here).

This is my code for click handler on anchor...

$(this).find('a[x-special="select-asset"]').click(function() {
    var evt = jQuery.Event('assetSelect', {
        url:        'this is url',
        closePopup: true,
    });
    var _parent = window.opener;
    _parent.jQuery(_parent.document).trigger(evt);
});

... and this is the code of event handler:

$(document).bind('assetSelect', function (evt) {
    console.log(evt);
});

This solution is fine, if you don't need to distinguish between multiple instances of the asset selection windows (only one window will dispatch "assetSelect" event). I have not found a way to pass a kind of tag parameter to window and then pass it back in event.

Because of this, I've chosen to go along with (at the end, better and visually more pleasant) solution, Fancybox. Unfortunately, there is no way - by default - to distinguish between instances either. Therefore, I've extended Fancybox as I've described in my blog post. I'm not including the full text of blog post here, because is not the topic of this question.

URL of the blog post: http://82517.tumblr.com/post/23798369533/using-fancybox-with-iframe-as-modal-dialog-on-a-web

๐ŸŒ
javaspring
javaspring.net โ€บ blog โ€บ javascript-window-open-from-callback
How to Make JavaScript window.open Open in a New Tab (Instead of Window) When Called from a Callback in Chrome & Opera โ€” javaspring.net
Synchronous tab opening: By calling window.open('about:blank', '_blank') directly in the click handler, the browser recognizes it as a user-initiated action and opens a tab. Async operation: The fetch call runs in the background, but the tab ...
๐ŸŒ
JavaScript.info
javascript.info โ€บ tutorial โ€บ frames and windows
Popups and window methods
It is null for all windows except popups. If you run the code below, it replaces the opener (current) window content with โ€œTestโ€:
๐ŸŒ
CodePen
codepen.io โ€บ nomaed โ€บ pen โ€บ dgezRa
window.open from jQuery ajax.success callback
function start(el) { var todoId = $(el).attr('docCredId'); $.ajax({ url: "https://jsonplaceholder.typicode.com/todos/" + todoId, success: function(data) { debugger; console.log("Response:", data); if (data) { debugger; var userId = data.userId; var url = "https://jsonplaceholder.typicode.com/users/" + userId; window.open(url, "_blank"); } }, error: function(error) { debugger; alert("Error:" + error); } }) } !
๐ŸŒ
W3Schools
w3schools.com โ€บ jsref โ€บ met_win_open.asp
Window open() Method
cssText getPropertyPriority() ... ... More examples below. The open() method opens a new browser window, or a new tab, depending on your browser settings and the parameter values....
๐ŸŒ
GitHub
gist.github.com โ€บ kaku87 โ€บ 6052362
javascript popup close callback event. ยท GitHub
June 16, 2016 - Clone this repository at &lt;script src=&quot;https://gist.github.com/kaku87/6052362.js&quot;&gt;&lt;/script&gt; Save kaku87/6052362 to your computer and use it in GitHub Desktop. ... This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
๐ŸŒ
Reintech
reintech.io โ€บ blog โ€บ tutorial-working-with-the-window-open-method
Working with the window.open() Method | Reintech media
January 13, 2026 - A common use case for window.open() is implementing OAuth authentication flows. Here's a complete example that handles popup blockers and communicates between windows: class OAuthHandler { constructor(authUrl, callbackUrl) { this.authUrl = authUrl; this.callbackUrl = callbackUrl; this.authWindow = null; } authenticate() { return new Promise((resolve, reject) => { // Open centered auth popup this.authWindow = openCenteredPopup( this.authUrl, 'oauth_window', 600, 700 ); if (!this.authWindow) { reject(new Error('Popup blocked.
๐ŸŒ
Mozilla Support
support.mozilla.org โ€บ en-US โ€บ questions โ€บ 953294
run code "window.open(url,...)" in javascript, the action is different according to the time this line of code is executed. | Firefox Support Forum | Mozilla Support
March 14, 2013 - clickIndirectly=function(){ require(['./js/testwindowopen/in.js'],function(){ window.open('http://google.com','_blank'); }) } clickDirectly = function(){ window.open('http://google.com','_blank'); } Hi jscher20000, the case used in our project is complex, so I made a test, there is no way to attach the attachment here, so I have to pasted the code in the end I used requirejs to require a js file, and in the callback function I called function window.open(url,'_blank') I tested them in different browsers, In firefox, click the button 'indirectly' it will open this window in a new tab.