Retrieve child window reference after refresh

后端 未结 5 1617
小鲜肉
小鲜肉 2021-01-17 18:32

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

相关标签:
5条回答
  • 2021-01-17 19:10

    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.

    0 讨论(0)
  • 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

    0 讨论(0)
  • 2021-01-17 19:20

    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.

    0 讨论(0)
  • 2021-01-17 19:23

    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)

    0 讨论(0)
  • 2021-01-17 19:28

    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.

    0 讨论(0)
提交回复
热议问题