Liquid Hotdog

JavaScript: Persisting a child window relation accross parents’ reloads.

I came across a fun issue with my pop-up flash mp3 player to be used on our new Vital website (coming soon.) I've designed a 'listen' button on the main shop website for each audio file preview. When this listen button is clicked on, a pop-up window is opened (if not already) and the flash player loads the respective audio file and begins playing. If a second listen button is clicked, the new track will be added to the existing play list and that track will begin playing. I discovered this method only worked when clicking listen links on the same parent page view. If the parent page is refreshed or a new page of the site is loaded, the reference to the pop-up window is lost. What then happens is any new listen link clicked will cause the pop-up page to reload from scratch and loose the play list. Whatever audio was playing stops, whatever tracks were in the play list are gone. Following, is my solution.

I've discovered that by saving an instance of the pop-up window object to the pop up itself, I can re-initialize the pop-up window object back on the parent window after a new page is loaded on the parent. Here's an example of the execution.

  1. Parent window begins reloading/browsing to a new page.
  2. Parent window sends a reference of the pop-up window to the pop-up.
  3. Pop-up window begins to continually check the parent window for a successful page load.
  4. Pop-up window sends the temporary instance of itself back to the parent window

Here's the code required to accomplish this:

Firstly, "wimpyWindow" is the name of the pop-up window. Here's the JavaScript that opens that window:

  1. <script type="text/javascript">
  2.     var wimpyWindow;
  3.     var winOpen=0;
  4.     function wimpyPopPlayer() {
  5.         wimpyWindow ='<ww :url page="/wimpy/wimpy.html"/>','wimpyMP3player','width='+windowWidth+',height='+windowHeight);
  6.         winOpen=1;
  7.     }
  8. </script>

Inside the parent window's <head> tag, create the following JavaScript. This function saves a copy (tempWindow) of the pop-up window object to the pop-up window, starts a function on the pop-up that continually checks the state of the parent window, and sets an indicator (parentRefreshed) that declares the parent page is refreshing.

  1. <script type="text/javascript">
  2.     var pageLoaded = false;
  4.     function window_onunload() {
  5.         pageLoaded = false;
  6.         if (winOpen==1) {
  7.             wimpyWindow.tempWindow = wimpyWindow;
  8.             wimpyWindow.checkParent();
  9.             wimpyWindow.parentRefreshed = true;
  10.         }
  11.         return true;
  12.     }
  13. </script>

In the parent window's <body> tag, add the following which will execute the above function whenever the parent window is reloaded or browses to a new page.

  1. <body onunload="window_onunload();">

At the bottom of the parent window add this small bit of JavaScript that notifies the scripts that the parent page is completely loaded.

  1. <script type="text/javascript">
  2.     pageLoaded = true;
  3. </script>

That's all the code for the parent window. Now, let's move on to the pop-up window's code. This is one nice function that monitors the state of the parent window and initializes the original pop-up window object on the parent window once the parent is done loading.

  1. <script type="text/javascript">
  3. var parentRefreshed = false;
  4. var tempWindow;
  6. function checkParent() {
  7.     try {
  8.         // import the parent window's page loading status.
  9.         var pageLoaded = window.opener.pageLoaded;
  11.         // if the parent window is loaded and it was just refreshed...
  12.         if (pageLoaded == true && parentRefreshed == true) {
  13.             // send a copy of the pop-up window object back to the parent
  14.             window.opener.wimpyWindow = tempWindow;
  15.             window.opener.winOpen = 1;
  16.             // set pageLoaded and parentRefreshed to false so we can tell when the next time the parent window is reloaded.
  17.             window.opener.pageLoaded = false;
  18.             parentRefreshed = false;
  19.             // exit the function so we don't keep running through the setTimeout()
  20.             return;
  21.         }
  22.     }
  23.     catch (e) {
  24.        // ignore errors
  25.     }
  27.     // cause this function to load continually till the above if statement is fulfilled.
  28.     window.setTimeout("checkParent()", 1000);
  29. }
  30. </script>

-- MrBlaQ
Filed under: Coding, Main — August 24, 2007 @ 5:40 pm
Valid XHTML 1.0 Valid CSS 2
eXTReMe Tracker