window.parent only works with iframes and window.opener works with separate windows.
On top of that, since I was trying to send a message to the parent window, but the new window was opened by the iframe IN that window.
So window.opener reached the iframe - then I had to actually send the message to its parent:
window.opener.parent.postMessage(etc, etc);
Answer from DAB on Stack OverflowVideos
The following works for me in chrome, firefox, ie(didn't test more browsers)
assume 3 documents
- (www.mydomain.com/parent.html)the page that contains the 'main'-document with the link
- (bills.mydomain.com/child.html)the page that will be opened by the link
- (www.mydomain.com/dispatcher.html)explained later
at first set the domain-property of all 3 documents to mydomain.com
<script>
document.domain="mydomain.com";
</script>
in parent.html create a hidden iframe with a name-property of e.g. "hiddenframe". Also create some function that may later receive a response.
parent.html should now look like this:
<script>
document.domain="mydomain.com";
function fx(msg)//receives the response
{
alert(msg)
}
</script>
<iframe name="hiddenframe" style="display:none"></iframe>
<a href="http://bills.mydomain.com/child.html" target="_blank">click</a>
In child.html you'll now be able to load a document into the hidden iframe inside parent.html
<script>
document.domain="mydomain.com";
window.open('http://www.mydomain.com/dispatcher.html','hiddenframe');
</script>
(don't be confused in face of the use of window.open() here, there will not open a new window, the page will be loaded into the iframe in parent.html)
In dispatcher.html you now may call the function inside parent.html
<script>
document.domain="mydomain.com";
parent.fx('you just got some response');
</script>
When you only need to reload the parent.html it's a little bit easier.
Again set the document.domain-property in parent.html and child.html(you don't need the iframe in parent.html and the dispatcher.html)
In parent.html also set the name-property of the window, e.g.
<script>
window.name="parentTab";
</script>
In child.html you now may access the parentTab-window(tab)
<script>
document.domain="mydomain.com";
window.open('http://www.mydomain.com/parent.html','parentTab');
</script>
...or simply use "parentTarget" as target-property of a link or form in child.html
What I did for myself, I implemeted some ajax to submit changes from the window2 into database. I implemeted JSON to pull new data from the database back to window1
It has worked now, earlier I was doing some syntax mistake. Here is the correct code for the same.
//parent Window
childWindow=window.open("http:/localhost/abcd.php","_blank","width=500,height=500");
childWindow.postMessage('message',"http://localhost:80/child.php");
//child Window
var newUrl='';
window.addEventListener(
"message",
function(e) {
console.log(e.data);//your data is captured in e.data
}, false);
If the child window you're referring to is an iFrame, then postMessage is the method you're stuck with.
Without seeing any of the code you've tried, it's hard to say what about your particular usage of postMessage isn't working – however, here is a link to a working postMessage example from an MDN article, as well as an article with a fully functional example you can dissect the code from.
One of these should be able to show you why your implementation isn't working.
The window.opener object is what you're looking for, used it from within your popup like so to call the a function of the parent window:
window.opener.yourFunc()
Here is a fun and easy demo that is heavily inspired by this answer to a similar question (but modified for my own purposes to help investigate the most difficult bug of my career).
Create 2 files (in the same directory) as follows:
parent.html
<button type="button" onclick="popup('popup.html', '', 800, 200);">Add My Card</button>
=>
<span id="retrievedData">No data yet.</span>
<script>
function popup(url, title, width, height) {
var left = (screen.width / 2) - (width / 2);
var top = (screen.height / 2) - (height / 2);
var options = '';
options += ',width=' + width;
options += ',height=' + height;
options += ',top=' + top;
options += ',left=' + left;
return window.open(url, title, options);
}
function setData(data) {
console.log(data);
var strData = JSON.stringify(data);
document.getElementById('retrievedData').innerHTML = strData;
var requestBinUrl = 'http://requestb.in/18u87g81';
window.location.href = requestBinUrl + '?data=' + strData;
}
</script>
popup.html
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<form id="popupForm" name="f">
<select id="urlField" name="url">
<option>
http://date.jsontest.com/
</option>
<option>
http://time.jsontest.com/
</option>
<option>
http://md5.jsontest.com/?text=HereIsSomeStuff
</option>
</select>
<div><input type="submit" /></div>
</form>
<script>
$('#popupForm').submit(function(e) {
e.preventDefault();
var url = $('#urlField').val();
console.log(url);
$.ajax({
url: url
}).then(function(data) {
console.log(JSON.stringify(data));
window.opener.setData(data);
window.close();
});
});
</script>
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
var eventer = window[eventMethod];
var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";
// Listen to message from child window
eventer(messageEvent,function(e) {
var key = e.message ? "message" : "data";
var data = e[key];
//run function//
},false);
Got it to work with the above in the parent page and the following in the child page -
parent.postMessage("loadMyOrders","*"); // `*` on any domain
Code copied from here.
Unpacked the accepted answer using newer ecma262 spec, and dropping ie8 support:
window.addEventListener('message', e => {
const key = e.message ? 'message' : 'data';
const data = e[key];
// ...
},false);
Relevant documentation:
- http://caniuse.com/#feat=addeventlistener
- https://developer.mozilla.org/en-US/docs/Web/API/Window/message_event#Examples