4

Is there a way to store global data in the window object such that the data can survive page reloads/refresh. So lets say I assign my global data/object -

window.myObject = myProductObject

And the user refreshes/reloads the page or may be jumps to another page of my website. Is window.myObject still available after the page reload?

NOTE -: I cannot store the object in a cookie, since its a object, I mean it could be a reference to another custom object or it could refer to another "window" object which has opened via "window.open"

kapso
  • 11,703
  • 16
  • 58
  • 76

4 Answers4

6

Use the window.top.name hack

var data = window.top.name ? JSON.parse(window.top.name) : {}
...
window.top.name = JSON.stringify(data)

window.top.name persists across page loads

I recommend you use an abstraction like lawnchair instead though

Raynos
  • 166,823
  • 56
  • 351
  • 396
4

You CAN save objects in cookies. But localStorage is better. Is similar to a cookie but you get 5Mb to use.

You have to JSON encode/decode if you save objects instead of strings, but that is easy with a wrapper on localStorage or cookie.

Here is a really simple wrapper for localStorage (you have 5Mb to use):

var Storage = {
    set: function(key, value) {
        localStorage[key] = JSON.stringify(value);
    },
    get: function(key) {
        return localStorage[key] ? JSON.parse(localStorage[key]) : null;
    }
};

And you can use it like this:

$(function() {
    var defaultValue = {param1: 'value',counter: 0 },
        myObj = Storage.get('myObj') || defaultValue; // get the obj from storage or create it with default values

    $('body').html('counter: ' + myObj.counter);
    myObj.counter+=1; // increment counter 
    Storage.set('myObj', myObj); // save it to localStorage
});
​

You can try it on this jsFiddle: http://jsfiddle.net/guumaster/LytzA/3/

Guumaster
  • 389
  • 3
  • 10
  • Also you can read this [Web Storage explained on Dev.Opera](http://dev.opera.com/articles/view/web-storage/) – Guumaster Mar 11 '12 at 12:43
1

You could try storing a string representation of your object in a cookie, provided the object is made up of values only (no methods), eg

var foo = { a: "a", b: "b" };
document.cookie = "foo=" + JSON.stringify(foo);

There's a good cookie reader / writer example here - https://developer.mozilla.org/en/DOM/document.cookie

Phil
  • 157,677
  • 23
  • 242
  • 245
  • Cookies is the _WRONG_ solution – Raynos Mar 11 '12 at 16:04
  • @Raynos Care to elaborate? It might not be the the most current solution (local storage is pretty cool but I'm old skool and didn't think of it immediately) but cookies *are* a solution to this problem – Phil Mar 11 '12 at 16:09
  • Cookies are send with every HTTP request, increasing bandwidth and latency. By all means if you need the data on the server and the client it's a correct solution, if you just need it on the client then it's a bad solution – Raynos Mar 11 '12 at 16:16
  • @Raynos Keep in mind the still [large number of browsers](http://www.quirksmode.org/dom/html5.html#localstorage) (including IE7) that do not support local storage. Depending on the OP's requirements, it may not even be an option – Phil Mar 11 '12 at 16:19
  • There are better hacks then cookies for IE7 support, `window.top.name` and `userData` come to mind. Neither send the cookies you store over the wire. – Raynos Mar 11 '12 at 16:31
1

I'm not sure how this fairs cross-browser. I at least got it to work in chrome, firefox and IE9 and IE8/7 in compatibility mode, but you will get warned about popups. You can detect if popups are being blocked and refuse to load anything until they are enabled for your site. See Detect blocked popup in Chrome

I'm using jQuery to bind to the beforeunload event, you can use your preferred solution.

jQuery(function ($) {
    $(window).bind('beforeunload', function () {
        window.open("", "_savedata", "titlebar=0,width=100,height=100").saveData = window.saveData;
    });

    var store = window.open("", "_savedata");      
    window.saveData = store.saveData;
    store.close();    
});

Example: (refresh the page a few times)

http://jsfiddle.net/hZVss/1/

And as requested by @Raynos - persisting closure state - something you can't serialise (works in firefox and chrome at least, IE calls it a security issue, but might be something to do with how jsfiddle is using frames)

http://jsfiddle.net/ght9f/2/

Disclaimer: I wouldn't vouch for the elegance of this solution. I was merely curious about persisting object state using popups. Serialising your object to JSON and storing it in a client side store is much better (@Raynos would recommend lawnchair https://github.com/brianleroux/lawnchair/). You should avoid cookies if you can as this data gets posted back to the server, which might not be ideal.

If your main objective was to persist references to popup windows you can actually do this by giving the popup a name. This is exactly how I am persisting my reference to the popup that I create on refresh.

Community
  • 1
  • 1
Matt Esch
  • 22,661
  • 8
  • 53
  • 51
  • 2
    Persisting state using popups is trolls – Raynos Mar 11 '12 at 16:05
  • 2
    Agreed. No need to reiterate in less helpful terms though. – Matt Esch Mar 11 '12 at 16:17
  • An answer is a recommended solution, not an academic aside on how it could be possibly solved. – Raynos Mar 11 '12 at 16:17
  • 1
    If you read the question you might notice that this answer actually answers the question. It is also the only way to truly persist the state, as JSON doesn't encapsulate the entire state, as mentioned by the OP. Ideal solution is to do it differently, but to solve the problem with the given constraints as asked by the OP, this is the only way. – Matt Esch Mar 11 '12 at 17:05
  • If your persisting state that's not serializable your doing it wrong – Raynos Mar 11 '12 at 17:25
  • 2
    If you need to persist state that is not serlizable, or decide you want to, for whatever reason, as the OP asks, this is the only way to do it. I would hope that the OP would see from the ugliness of the solution that it's a better idea to consider a different approach, but I'm not going to make that decision. – Matt Esch Mar 11 '12 at 17:31