Click here to Skip to main content
15,885,244 members
Articles / Web Development / XHTML
Article

JavaScript to close child windows

Rate me:
Please Sign up or sign in to vote.
4.73/5 (9 votes)
12 Sep 2008CPOL2 min read 104.4K   878   20   11
How to close open child windows when parent window is closed, using JavaScript.

How to Close Child Windows When the Parent Window Closes

The Motivation

When moving an application from Windows to web, I noticed that certain functionality available only in a Windows Form is expected to be carried over to the web form. Unfortunately, sometimes, achieving the said functionality can be a bit more difficult than expected.

The Objective

Being object oriented in nature, I wanted a drop in solution on the client side to achieve closing child windows. Doing a bit of research told me that the call to window.open would return a window object that I could then (at a later time) call close on. The question to be answered was how to store each window object upon opening, and how to detect the browser closing in order to close the child windows.

Note: There are more than a few articles out there on creating objects in JavaScript, and it is beyond the scope of this article.

The Code

Persisting Window Handles

The first thing, persist the window object returned by the open function call. I achieved this by storing it as a private Array within my object.

function windowController(){
  //Note: The absence of "this" indicates private
  var loadedWindows = new Array()
  …..
} //Note: Yes, in JavaScript an object
  // is declared similar to a function.

Encapsulate window.open

Now that I have a nifty array, I need a public method that would wrap the window.open function to capture the returned object and add to my array.

JavaScript
this.popUpWindow = function(wndUrl, wndName, wndWidth, wndHeight){
var windObj = null;
try
{
  //set default width 
  if(typeof wndWidth == 'undefined') wndWidth=500;
  //set default height
  if(typeof wndHeight == 'undefined') wndHeight=250;
  windObj = window.open(wndUrl, 
    //misc options to open a window, again mostly optional 
    wndName, 'toolbar=0,menubar=0,resizable=0,location=0,
    directories=0,width='+wndWidth+',height='+wndHeight); 
  windObj.registerID = wndName; //this is the key to the window
  loadedWindows[loadedWindows.length] = windObj;
  //add the window to our collection.
}
catch(ex) { 
  alert('WindowController.popUpWindow: ' + 
        'Exception occured, message: ' + ex.message)
} //oops, looks like we are cross domain scripting.
return windObj;
}

Further Enhance Encapsulation

Since I am wrapping window.open, I decided to only allow a single instance of each handle ID to be opened, by checking the ID against each window handle already loaded, and if it exists, I simply call focus (this is similar to what is expected from Windows Forms).

JavaScript
this.popUpWindow = function(wndUrl, wndName, wndWidth, wndHeight){
  var windObj = null;
  try{
    windObj = findWindow(wndName);
    if (windObj != null)
    {
      windObj.focus();
    }
    else
    {
     ......
    }

where the findWindow function simply iterates the array, and returns null if not found.

JavaScript
function findWindow(winHandle){
  for (var i=0; i< loadedWindows.length; i++){
  if (loadedWindows[i].closed == true){
    loadedWindows.splice(i,1);
    i--;
  }
  else{
    if (loadedWindows[i].registerID == winHandle)
      return loadedWindows[i];
    }
  }
  return null;
}

Pulling it all Together

Finally, I needed a way to know when the browser was closing in order to close all my child windows. Of course, IE, compared to other browsers, has different ways to register to events, so I created a generic method to achieve this.

JavaScript
function WireEvent(elem,target,func){
  if (elem.addEventListener)
    elem.addEventListener(target, func, false); //FF
  else if (elem.attachEvent)
    elem.attachEvent(target, func); //IE
  }
  WireEvent(window,'onunload',_windowController.closeAllWindows);

where the onunload function is handled as follows:

JavaScript
this.closeAllWindows = function(){
  for(var x = 0; x < loadedWindows.length; x++){
    try{
      loadedWindows[x].close();
    }
    catch(err) {
      alert('WindowController.closeAllWindows: ' + 
            'Exception occured, message: ' + err.message)
    }
  } //oops, cross domain scripting or window already closed etc...
}

Looks like all is in place, the last thing I needed was the ability to init the object so it would be available from code, so I added the call at the top of the js file, as follows….

JavaScript
var _windowController = new windowController();

Using the Object

Now, if the file is included, we have access to the window controller, so as long as all opened child windows are done through this object, we can be certain they will close upon browser exit as long as we are not cross domain.

JavaScript
_windowController.popUpWindow('ChildForm.aspx', 'ChildForm');

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
United States United States
Ah, just another dev living the life of Dilbert. Smile | :)

Comments and Discussions

 
QuestionWhen I run your code, no popup window is closed when I close the main browser Pin
Member 813707623-May-17 4:51
Member 813707623-May-17 4:51 
QuestionNeed a sample code with pages Pin
Member 103865067-Nov-13 3:26
Member 103865067-Nov-13 3:26 
QuestionHow to wait for child Pin
Greg Bergeron4-Aug-11 5:15
Greg Bergeron4-Aug-11 5:15 
This article is a godsend. Thank you very much. It works great but I have a request/question. In our code, the child window needs to save some information into the parent before the parent goes away. The child brings up a dialog asking if the user would like to save the changes or not. Using this code, when you close the parent, it tries to close the child (which displays the dialog and waits for the user), then the parent goes away. Once the user tries to save the changes, there's nowhere for it to go because the parent is already gone. How can we wait for the user response in the child window before closing the parent? I've tried using WireEvent with 'onbeforeunload' but that gets called when the user changes pages (and not just closing the parent). I've tried this: after closing all windows, waiting for the windows with:
JavaScript
if (window.closed)
but that doesn't work either. Any tips?
GeneralNice article! Pin
Sandeep Mewara23-Mar-10 8:02
mveSandeep Mewara23-Mar-10 8:02 
GeneralExcellent code Pin
Edwill Leighton25-Jun-09 5:35
Edwill Leighton25-Jun-09 5:35 
Generalgood Pin
axkiller2-Jun-09 23:34
axkiller2-Jun-09 23:34 
GeneralNice article but incomplete solution Pin
Vikas Misra(TCS)24-Nov-08 23:07
Vikas Misra(TCS)24-Nov-08 23:07 
GeneralPrb downloading your sample Pin
pMeric15-Sep-08 20:01
pMeric15-Sep-08 20:01 
GeneralRe: Prb downloading your sample Pin
MCF.Goodwin16-Sep-08 0:20
MCF.Goodwin16-Sep-08 0:20 
GeneralRe: Prb downloading your sample Pin
pMeric16-Sep-08 1:19
pMeric16-Sep-08 1:19 
GeneralInteresting article Pin
o_theophilus15-Sep-08 6:29
o_theophilus15-Sep-08 6:29 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.