1

I know there are many questions of this ilk with many answers.

I know that I can use

var popup = window.open('');

and can later use

popup.close();

to close that window.

However, is there a way to close all children without having to store the window.open result?

That is, could I do

window.open('1');
window.open('2');
window.open('3');

and then somehow do a global "Close" call that will close these three windows?

If not, could I accomplish it by using the following code to do the open?

window.open('1','window1');
window.open('2','window2');
window.open('3','window3');
tshepang
  • 12,111
  • 21
  • 91
  • 136
David
  • 108
  • 1
  • 1
  • 9
  • You could store the window objects returned by `open()` in a global array, or maybe in an object, indexed by window name. Then you would only have to iterate over this array / object. – Frédéric Hamidi Jul 19 '13 at 22:22

2 Answers2

7

You can make a new function that basically wraps the existing functionality with what you're trying to do.

var WindowDialog = new function() {
    this.openedWindows = {};

    this.open = function(instanceName) {
        var handle = window.open(Array.prototype.splice.call(arguments, 1));

        this.openedWindows[instanceName] = handle;

        return handle;
    };

    this.close = function(instanceName) {
        if(this.openedWindows[instanceName])
            this.openedWindows[instanceName].close();
    };

    this.closeAll = function() {
        for(var dialog in this.openedWindows)
            this.openedWindows[dialog].close();
    };
};

Sample Usage

WindowDialog.open('windowName', /* arguments you would call in window.open() */);
WindowDialog.open('anotherName', /* ... */);
WindowDialog.open('uniqueWindow', /* ... */);
WindowDialog.open('testingAgain', /* ... */);
WindowDialog.open('finalWindow', /* ... */);

// closes the instance you created with the name 'testingAgain'
WindowDialog.close('testingAgain');

// close all dialogs
WindowDialog.closeAll();
Austin Brunkhorst
  • 20,704
  • 6
  • 47
  • 61
  • I didn't downvote and I like your approach better than the other answer but there are a couple things wrong with it. First, `arguments` isn't a real array so you can't call `splice` on it. Instead you want to do something like `Array.prototype.splice.call(arguments,1)`. Also, the `new function()` pattern seems a little odd. You could make it an object literal instead `{ openWindows : {}, open : function(instanceName)...}`. – go-oleg Jul 19 '13 at 22:49
  • You're right about `arguments` - good to know. As for the `new function()` pattern, I can't access `this` keyword in an object literal. – Austin Brunkhorst Jul 19 '13 at 23:00
  • You should be able to. [jsfiddle](http://jsfiddle.net/TBVcJ/) – go-oleg Jul 19 '13 at 23:04
2

try this to open and close

document.MyActiveWindows= new Array;

function openWindow(sUrl,sName,sProps){
document.MyActiveWindows.push(window.open(sUrl,sName,sProps))
}

function closeAllWindows(){
for(var i = 0;i < document.MyActiveWindows.length; i++)
document.MyActiveWindows[i].close()
}
Daniel Ezra
  • 1,424
  • 3
  • 14
  • 21
  • Using global variables isn't a good idea. Using a name (activeWindows) that sounds like something that might actually be used by a browser in the future is even worse. – go-oleg Jul 19 '13 at 22:29
  • @go-oleg, sometimes there is global state to be maintained, and even though I agree expanding `document` is not a good idea, expanding `$` or another global object should not be frowned upon, when you have to. Closures for the sake of closures are not always the right way to go. – Frédéric Hamidi Jul 19 '13 at 22:32
  • 1
    @FrédéricHamidi: Good point. The important thing is to namespace them properly to avoid conflicts. – go-oleg Jul 19 '13 at 22:35