Ajax is great for sending data back and forth between a browser window and the server, but when it comes to communication between two browser windows, there are few libraries that can help you out there.
I’ve been working with jQuery for over a year now and have always wanted to give something back to the user community by releasing my own plugin. Unfortunately it seemed like every type of generic functionality I might ever need had already been developed by others. Until last night.
I was working on a webapp in which my main browser window had to open a popup window, and the user would then perform an action in this window. Upon completion of that action the main (parent) browser window needed to be notified.
Though parent and child window can easily access eachother’s DOM, a common way to get a value from one window to another is by setting a value on a hidden input field of a form in the other window. This requires you to add form markup to your page, which is clunky. A second issue is that if you have several types of events or data to send to the other window, you’ll need to add an input field for each type. And a third issue I ran into is that ‘change’ events do not seem to fire for an input field if that field was updated by another window. ‘change’ or custom events using jQuery didn’t work either this way. ‘click’ events on links or buttons do work, but they would need to be hidden, otherwise the user could click on them too. I got it all working but this all started to look like an ugly hack, cluttering my pages with messy javascript and markup code.
Long story short, this is where my new skills of creating jQuery plugins came to the rescue. This could all be put into a nice little plugin that would hide all the messy details of adding a form to your page and using hidden form elements to transfer data back and forth between windows. Even better, my new plugin makes it very easy to use multiple callback handlers, so you can define your own events that you can send from one browser window to the other. And events can be sent both ways in almost the same fashion. To my delight, it worked flawlessly in all browsers I’ve tried (FF, safari on Mac, and FF and IE7 on Windows).
Here’s how to use it:
In any page that needs to receive window events, make sure to call the initialization function upon page load:
$.initWindowMsg();
The parent window can open a child window the good old way:
childWin = window.open('child.html', 'mychildwindow');
and then send it an event with data:
$.triggerWindowEvent(childWin, "myevent", "some data");
The child window can register a callback handler for this event as follows:
$.windowMsg("myevent", function(message) {
// do something with message from parent
});
The child window can send a message back to the parent with:
$.triggerParentEvent("parentevent", "message to parent");
The parent can register a handler for this event in the same way:
$.windowMsg("parentevent", function(message) {
// do something with message from child
});
That’s all.
You can see a simple demo here. (make sure your popup blocker is turned off).
Download the plugin and demo files
One thing to keep in mind is that it is of course a requirement that one of the windows opened the other, and that neither window has navigated to any other pages. Once they’ve lost the reference to eachother, there’s no reconnecting. The triggerWindowEvent and triggerParentEvent functions return a boolean which indicates if the event could be sent or not. I could pretty easily add a function that could check if the parent or child window is still there actually… will add that in the first update of the plugin.
May 26th, 2008 on 1:24 am
Very helpful tutorial. Thanks
December 22nd, 2008 on 4:30 am
Very good jquery-plugin, exactly what I need here.
Thanks!
October 16th, 2012 on 4:51 am
Does this work cross domain i mean to say for communication between two windows in different domain.
March 11th, 2009 on 9:50 am
Good stuff – worked the first time with no fuss and easy to follow tutorial.
May 9th, 2009 on 12:24 pm
Thank you so much, this is what i am looking for, and its very useful on my pop up player on my website,
July 25th, 2009 on 10:33 am
Very good jquery plugin, but not for IE8 !!!
February 15th, 2011 on 9:30 am
Yes, very great plugin, except it doesn’t work in IE8, but then again what does? Thank you and i’ll post if I find a way to make it work in IE8!
February 15th, 2011 on 10:35 am
Ok, found something that works, at least for an event from child to parent in IE8. First off don’t use window.open(), in my script, I used window.showModalDialog(). You should pass the parent window as an argument to showModalDialog(), as such:
onclick = ‘window.showModalDialog(\”page.php\”, window);’
next change line #41 in peter’s script from:
$.triggerWindowEvent(window.opener, event, msg);
to:
$.triggerWindowEvent(window.dialogArguments, event, msg);
That’s what did the trick for me, but I only needed the one way communication. Good luck!
March 3rd, 2011 on 2:21 pm
thanks for the feedback Frank, I’ve actually started using this plugin myself again recently, and I’ll try to incorporate your changes along with a couple of other improvements I was planning on making.
June 23rd, 2011 on 12:59 pm
Hi,
Is this plugin being actively worked on, either in github or somewhere?
I would like to use and make contributions to it.
Thanks!!
August 24th, 2011 on 3:48 am
I’ve high hopes for this plugin! I need to communicate between a page and an iframe on that page – can you give an example of how that might work?
thanks!
Al;
August 26th, 2011 on 6:59 am
Hey,
unfortunately I can’t get triggerWindowEvent to work on a child window using the current FF and the current Opera – the form fields’ values get set correctly, but the “click” event doesn’t get fired. Triggering a parent function from a child window works, though.
August 26th, 2011 on 7:12 am
Nevermind my last comment. It works.
September 18th, 2011 on 12:12 pm
Does the job with typical jquery simplicity.
Great plug in
May 2nd, 2012 on 7:37 pm
Hi,
Thank you for this tutorial, if for example the child window return lot of raws data how can we accomplish this :
the user click in a row, that row data will transfer to the parent ?
thanks
your help is appreciated.
May 13th, 2012 on 5:32 am
excellent… It is working on iPad Safari as well. You saved my life
.
June 7th, 2012 on 3:12 pm
Tested it with IE 8 and works just fine.
August 31st, 2012 on 1:20 am
Hi,
excellent plugin, does exactly what it needs to.
Do you still intend to upgrade it, as you mention at the end of your post ?
Cheers
William
August 31st, 2012 on 10:53 am
I’m not using it myself anymore but may do a new revision if there’s demand for it. Since I wrote this plugin, a new HTML5 feature has been developed that would actually make this even easier: the postMessage API (link here). However I don’t know how well this feature is supported in older browsers like IE7 or IE8. I would rewrite my plugin to use the postMessage API by default but fall back on my old approach if necessary.
The syntax of this API is very similar to mine. Depending on what kind of browser support you need, the postMessage API may be all you need.