0

I'm keeping track of child windows being opened from a parent page. The following code works as partially as expected, but with an important flaw. Whenever I execute the postback, it reloads the JavaScript and it erases the global variable.

My proposed solution

I thought of adding the object to the sessionStorage with the following line of code;

            sessionStorage.setItem(thiskey, winInst);

However, I'm getting an error: JavaScript runtime error: Circular reference in value argument not supported.

The value being added is a window object.

Here's the working code without the sessionStorage line.

var openedWindows = {};

setInterval(checkIfWindowIsClose, 40);

function openThisWindow(popLoc, attributes, id) {
    var winInst = window.open(popLoc, attributes, id);
    openedWindows["clickedRow" + id] = winInst;
}

function checkIfWindowIsClose() {
    var id = "";
    for (var i in openedWindows) {

        if (openedWindows[i].closed) {
            console.log(i);
            delete openedWindows[i];
            id = (' ' + i).slice(1);
            id = id.replace("clickedRow", "");

        }
    }
    if (id !== "") {

        __doPostBack('upList.UniqueID', id.toString());
        id = "";
    }

}

Goal

Keep track of the openedWindows dictionary after a page reload.

How can I achieve this with sessionStorage?

Thank you,

Fran Martinez
  • 677
  • 4
  • 15
  • 36

2 Answers2

1

sessionStorage and localStorage only store strings as values, while the window object cannot be serialised to a string.

What you can do here is, store a reference to the name of the window object.

The window.open function allows you to open a new window and give a name to it in the second parameter, you can then access and refocus on the said window using the window.open method by passing in the name as the second parameter, if a window with that name is not open already, it'll open a new window.

Instead of trying to save the complete window instance in the session storage, you can save the name of the window only.

Refer: Check if window is already open window.open

Community
  • 1
  • 1
DesTroy
  • 390
  • 4
  • 17
  • You are correct. I can not achieve the end goal with local storage or with session storage. I had to follow a more complex workaround, but are also correct in terms that I need to follow information from the window object. However; I'm didn't test the name/second parameter of the window function. – Fran Martinez May 19 '17 at 17:32
1

I followed the advice presented in this post:

Javascript: persist window object refrence?

This is my code:

Parent

    var openedWindows = {};
    var child = {};

    setInterval(checkIfWindowIsClose, 40);

    function openThisWindow(popLoc, attributes, id) {
        var winInst = window.open(popLoc, attributes, id);
        openedWindows["clickedRow" + id] = winInst;

    }

    function checkIfWindowIsClose() {
        var id = "";

        for (var i in openedWindows) {

            if (openedWindows[i].closed) {
                // i is the id of your window and here you know that your window with id has been closed
                // here remove also the window from the object otherwise you will keep also the instance of the closed one
                console.log(i);
                child = openedWindows;

                id = (' ' + i).slice(1);
                id = id.replace("clickedRow", "");
                delete openedWindows[i];
            }
        }

        if (id !== "") {

            __doPostBack('upList.UniqueID', id.toString());
            id = "";
        }
    }

    // Update openedWindows references if parent page (this page)
    // has reloaded. 
    function linkParent(window, id) {
        window.opener.child = window;
        var thiskey = "clickedRow" + id;
        openedWindows[thiskey] = window;

    }

    // Let the child windows know that they must
    // send back to this parent page; their prent- window references
    // for when parent page has reloaded.
    window.onunload = function() {
        if (child.length !== 0)
        {
            for (var i in child) {

                child[i].expire();

            }
        }

    };

Child

    // Execute call to function once two second has passed.
    function expire() {
        setTimeout(function () { referToTop(window.opener); }, 2000);
    }

    // Retrieve record being inspected, window object and sending those
    // parameters back to the parent page -> Parent.aspx
    function referToTop(thisOpener) {
        var id = getUrlParameter('id'); 
        thisOpener.top.linkParent(window, id);
    }

    // Retrieve query information from page.
    function getUrlParameter(name) {
        name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
        var regex = new RegExp('[\\?&]' + name + '=([^&#]*)');
        var results = regex.exec(location.search);
        return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '));
    };
Community
  • 1
  • 1
Fran Martinez
  • 677
  • 4
  • 15
  • 36