I have an HTML5 offline app (i.e. there\'s no server-side component/code).
It basically has two windows (parent and child). However, in some instan
I achieved this scenario using Window.postMessage, which enables cross-origin communication between Window objects. It supports: https://caniuse.com/#feat=mdn-api_window_postmessage
Basic working example for establishing communication between parent and child Window objects
In the parent app,
var childWindow = window.open(CHILD_URL);
setTimeout(() => { // postMessage on some browsers may need setTimout
childWindow.postMessage( // STEP 1
"INITIATE_CONNECTION", // message
CHILD_URL // targetOrigin
);
}, 500)
function receiveMessageFromChild(event) {
if (event.origin === CHILD_URL) { // we should always check with the event.origin
if (event.source) {
if (event.data === "CONNECTION_SUCCESSFUL") {
setTimeout(() => {
event.source.postMessage( // STEP 3 and STEP 7
"SEND_SOME_DATA_TO_CHILD",
CHILD_URL);
}, 500);
}
// other messages handling from child
}
}
}
if (window.addEventListener) {
window.addEventListener("message", receiveMessageFromChild, false);
} else if (window.attachEvent) { // for IE
window.attachEvent("onmessage", receiveMessageFromChild);
}
In the child app,
function receiveMessageFromParent(event) {
if (event.origin === PARENT_URL) { // we should always check with the event.origin
var parentWindow = window.opener || event.source;
if (parentWindow) {
if (event.data === "INITIATE_CONNECTION" || event.data === "RE_NITIATE_CONNECTION") { // "RE_NITIATE_CONNECTION" msg from parent when parent is refreshed
setTimeout(() => {
parentWindow.postMessage( // STEP 2
"CONNECTION_SUCCESSFUL",
PARENT_URL);
}, 500);
}
// other messages handling from parent
}
}
}
if (window.addEventListener) {
window.addEventListener("message", receiveMessageFromParent, false);
} else if (window.attachEvent) { // for IE
window.attachEvent("onmessage", receiveMessageFromParent);
}
To handle parent window refresh and retrieve child window reference after the parent refresh make the following changes in the above codes,
In the parent app,
document.body.onunload = () => { // before refreshing parent, this function will be called
if (childWindow) {
setTimeout(() => {
childWindow.postMessage( // STEP 4
"PARENT_REFRESHING",
CHILD_URL
);
}, 500);
}
};
function receiveMessageFromChild(event) {
// ... above mentioned code in the parent app for this function
.
.
.
// other messages handling from child
if (event.data === "PARENT_REFRESHED") {
setTimeout(() => {
event.source.postMessage( // STEP 6 - this event.source is a child window reference
"RE_NITIATE_CONNECTION",
CHILD_URL
);
}, 500);
}
}
In the child app,
function receiveMessageFromParent(event) {
// ... above mentioned code in the child app for this function
.
.
.
// other messages handling from parent
if (event.data === "PARENT_REFRESHING") {
setTimeout(() => {
event.source.postMessage( // STEP 5
"PARENT_REFRESHED",
CHILD_URL
);
}, 500);
}
}
In the above example, please refer to the STEPs from 1 to 7. STEP 6 is the child window reference when the parent is refreshed.
You can obtain the reference of child window simply by following trick.
newWin = window.open("", "child_window_name", "width=...");
if (newWin.location.href === "about:blank") {
newWin = window.open("a.html", "child_window_name", "width=...");
} else {
// We've already obtained the reference.
// However, IE and FireFox won't put focus on an already opened window.
// So we have to do that explicitly:
newWin.focus();
}
Note you must have a fixed child window name to make this trick works.
Example URL: http://josephj.com/lab/2011/window-open-reconnect/demo.html
Can you call something on your opener that tells it to reload and reopen the popup to a page?
e.g.
//in popup
window.opener.doReload('popup_page_name.html');
window.close();
//in opener
function doReload(popupURL){
setSomeFormField(popupURL);
someForm.submit();
}
then in your server-side code, if you had the popup set, add the code to re-launch it.
See here: http://www.w3.org/TR/html5/offline.html#dom-appcache-update
applicationCache.addEventListener("updateready", function() {
applicationCache.swapCache();
//now reload the body html
}, false);
setInterval(60000, applicationCache.update);//check for updates every minute
(updateready
fires every time a new version has been downloaded)
Sounds like a pretty complex solution. Why don't you put the content of the parent window in an invisible iframe (i.e. one without a border) and just refresh the frame?
That would allow you to save the reference to the frame and child window in the top document where both could access it.