Set a Callback Function to a New Window in JavaScript

Set a callback function to a new window in javascript

Updated for comments: If you're opening your window via window.open() then in your child page you can set a function in the child to just be a reference pointing to a parent function, so have this in the child page:

var RunCallbackFunction = function() { }; //reference holder only

Then in your parent (opener), set that function when that child window loads, like this:

//random function you want to call
function myFunc() { alert("I'm a function in the parent window"); }

//to actually open the window..
var win = window.open("window.html");
win.onload = function() { win.RunCallbackFunction = myFunc; };

This assigns the function in your parent to now be the target of that child...and you can point each child to a different function if you wish, they're all independent.

Callback function opens new window

Is there any possible trick to use here.

Not really, no. As you've indicated, the issue is that the browser sees you trying to open a popup not during the processing of a user event, and quite correctly prevents you from doing that. Options:

  1. Your best bet is not to open a new window, but to use modern techniques to open a window-within-the-existing-window (e.g., absolutely-positioned divs and such).

  2. You can have the callback show a new button (or whatever UI you like) that the user then clicks to open the window using the information the callback received. E.g. "Your results are ready, [click here] to view them in a new window." Since you're then opening the window within a user action again, the browser will allow it.

  3. A very poor third choice to either of the above would be to make whatever you're doing that triggers the callback (ajax, I'm guessing) synchronous, so that the window.open occurs during the handling of the user event. But of course, synchronous ajax is a Bad Idea(tm)...


Re your edit: So for instance, #2 above would be that checkDoc shows something in the UI saying the document is ready, and offers a link to click to open it.

Callback function call when child window is close

You may call a parent function from child window this way:

window.opener.your_function()

To call a child function in parent window:

var w = window.open(somelocation,''); //has a function on `window` called "test"
w.test();

If any of this tips help you, you may show us how the callback approach was used by you.

Hope this helps you.

Regards!

Callback for a popup window in JavaScript

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

Programmatically opening a new tab within a callback

I was able to hack my way around by serving a intermediate page (say '/sameDomainDummySpinnerPage') and then redirecting in the callback.

$('#linktest').click(function(){
var childWindow = window.open('/sameDomainDummySpinnerPage');
setTimeout(function() {
childWindow.location.replace('http://yahoo.com');
}, 3000);
});

Another way around that I came upon was setting the 'target' attribute to a unique string. In the callback window.open on the same target affects the previously introduced tab. But this leads to a deteriorated user experience. The user may use the tab, your script opened, to surf the web. On re-running, your script will:
1. override tab's existing window.location
2. may not allow .focus(); causing the user to miss out on the response of their action

ref:
https://developer.mozilla.org/en-US/docs/Web/API/Window.open#Do_not_use_target.3D.22_blank.22
http://www.infimum.dk/HTML/JSwindows.html
Bypass popup blocker on window.open when JQuery event.preventDefault() is set

Passing Params to a Window[callback] Function

Are you talking about JSONP? If so, you don't call the callback or pass in the argument at all, the code returned by the API does.

E.g., your code:

window.myCallback = newCallbackFunction;

function newCallbackFunction(data) {
// use the data
}

(I'm assuming this isn't at global scope, hence assigning to the window object.)

...plus your code for initiating the JSONP call, which is usually appending a script element to your page with a URL containing the name of the callback ("myCallback" in the above).

Their response will look like this:

myCallback({
// data here
});

...which, when it arrives, will run (because it's the content of a script element), and will call your function. This is how JSONP works.


If you want to include further arguments for the function, all you do is have the callback they call turn around and call your target function, e.g.:

window.myCallback = function(data) {
newCallbackFunction(data, "foo", "bar");
};

function newCallbackFunction(data) {
// use the data
}

Now when their code calls the global myCallback, all it does is turn around and call newCallbackFunction with that data and the arguments you specify.

Those arguments don't have to be literals as in the above. Here's an example with a bit more context, using a closure:

// Assume the url already contains the name of the callback "myCallback"
function doJSONP(url, niftyInfo, moreNiftyInfo) {
var script;

// Set up the callback
window.myCallback = function(data) {
// Runs when the data arrives
newCallbackFunction(data, niftyInfo, moreNiftyInfo);
};

// Trigger the request
script = document.createElement('script');
script.src = url;
document.documentElement.appendChild(script);
}

Ideally, though, when doing JSONP you auto-generate the name of the callback each time so that it's specific to the request (in case you have two outstanding requests at the same time):

// Assume the url ends with "callback=" and we append the name of the
// callback function to it
function doJSONP(url, niftyInfo, moreNiftyInfo) {
var cbname, script;

// Get a callback name
cbname = "callback_" +
new Date().getTime() +
"_" +
Math.floor(Math.random() * 10000);

// Set up the callback
window[cbname] = function(data) {
// Remove us from the window object
try {
delete window[cbname];
}
catch (e) { // Handle IE bug (throws an error when you try to delete window properties)
window[cbname] = undefined;
}

// Runs the function
newCallbackFunction(data, niftyInfo, moreNiftyInfo);
};

// Trigger the request
script = document.createElement('script');
script.src = url + encodeURIComponent(cbname);
document.documentElement.appendChild(script);
}

Is there a way to have an onload callback after changing window.location.href?

No, you cannot do it the way you want. Loading a new page closes the current document and starts loading a new document. Any code in your current document will no longer be active when the new page starts to load.

To have an event handler when the new document loads, you would either need to insert code into the new page's document or load the new document into an iframe and monitor the loading of the iframe from your current document.

Hoisting TypeScript callback function to window object

An ugly workaround would be to assign your callback function to a variable below window by hand:

import { nativeThingEventHandler } from 'somewhere';

(window as any).nativeThingEventHandler = nativeThingEventHandler;


Related Topics



Leave a reply



Submit