How to save and restore the whole site using Javascript?

Hi, I am developing my own javascript api router. It performs routing based on #FregmentIdentifiers (document.location.hash).

Api almos is finished, but I'm still working on the backbuttom event. Whenever the backbuttom is clicked and the hash has changed and been seen before, the old content will be restored.

Do you know a way to save and restore all content?

My problem is that if I save and restore document.body.innerHTML, then only the markup will be restored, but not events, i.e. googlemaps stops working. I tried to clone document.body or document.documentElement, but javascript either told me that there is no setter in the field or that my clone is invalid.

EDIT:

To clearly understand what I'm working on, I decided to publish my current code. The question is about parts marked by comment // TODO.

function Router(){ var that = this; var router = this; var executionObservers = []; that.routes = []; this.registerRoute = function(route){ that.routes.push(route); }; var history = null; this.init = function(){ var i; var identifier = document.location.hash; history = new History(); history.start(); if(identifier.length > 0){ identifier = identifier.substring(1,identifier.length); for(i = 0; i< that.routes.length; i++){ var route = that.routes[i]; if(route.contains(identifier)){ route.getAction(identifier)(route.getParams(identifier)); return true; } } } return false; }; this.executed = function (identifier){ var i; for(i=0; i<executionObservers.length; i++){ executionObservers[i](identifier); } document.location.hash = identifier; }; this.addExecutionObserver = function(observer){ executionObservers.push(observer); }; function History(){ var history = []; var timeout = 200; var lastAddedHash = null; var loop = function(callback){ var hash = window.location.hash; window.setTimeout( function(){ if(window.location.hash!=hash){ hash = window.location.hash; callback(hash); } loop(callback); }, timeout ); }; this.add = function(hash){ lastAddedHash = hash; window.setTimeout(addCallback(hash), timeout); }; addCallback = function(hash){ return function(){ var i; var found = false; for(i =0; i< history.length&&!found; i++){ if(history[i][1] == hash){ found = true; //TODO create backup //history[i][0] = } } if(!found){history.push(new Array(document.documentElement.cloneNode(true),hash));} } } this.setTimeout = function(micoseconds){ timeout = microseconds; }; started = false; this.start = function(){ if(!started){ started = true; loop(function(hash){ var i; if(lastAddedHash!=null&&hash!=lastAddedHash){ for(i =0; i<history.length; i++){ if(history[i][1] == hash){ //TODO restore from backup document.location.reload(); } } } }); } }; router.addExecutionObserver(this.add); } } Router.instance = null; Router.getInstance = function(){ if(Router.instance === null ){ Router.instance = new Router(); } return Router.instance; }; /** * @param getParams = function(identifier) * @param getIdentifier = function(params) * @param contains = function(identifier) */ function Route(action, getParams, getIdentifier, contains){ var that = this; var router = Router.getInstance(); this.contains = contains; this.getParams = getParams; this.getAction = function(){ return action; } this.reExecute = function(identifier){ action(getParams(identifier)); }; this.execute = function(params){ action(params); this.executed(params); } this.executed = function(params){ router.executed('#' + getIdentifier(params)); }; this.register = function(){ router.registerRoute(this); }; } function PrefixedRouterConfig(prefix,paramRegexes){ this.contains = function(identifier){ var regex = "^" + prefix; for(var i=0;i<paramRegexes.length;i++){ regex+="_"+paramRegexes[i]; } regex +="$"; var match = identifier.match(regex); return match != null && (typeof match) == 'object' && (match[0] == identifier); }; this.getIdentifier = function(params){ ret = prefix; for(var i=0;i<params.length;i++){ ret+="_"+params[i]; } return ret; }; this.getParams = function(identifier){ var regex = "^" + prefix; for(var i=0;i<paramRegexes.length;i++){ regex+="_("+paramRegexes[i]+")"; } regex +="$"; var matches = identifier.match(regex); var ret = []; for(var i=1;i<matches.length;i++){ ret.push(matches[i]); } return ret; }; } 

An example of using my api might look like this:

 config = new PrefixedRouterConfig('show_map',new Array("\\d+", "-?\\d+(?:\\.\\d+)?", "-?\\d+(?:\\.\\d+)?")); var ROUTE_SHOW_MAP = new Route( function(params){ var zoom = params[0]; var lat = params[1]; var lng = params[2]; MyGmapInterface.preparePage(-1); addTabSelectedCallback(MyGmapInterface.tabLoaded); addTabClosedCallback(MyGmapInterface.tabClosed); MyGmapInterface.tabsLoaded = true; MyGmapInterface.myMap = new MyMap(lat,lng,zoom,MyGmapInterface.getMapContainer(),MyGmapInterface.notCompatible); MyGmapInterface.addNewCamMarkers(MyGmapInterface.loadCams()); MyGmapInterface.initListeners(); tabSelected(TAB_LEFT); }, config.getParams, config.getIdentifier, config.contains ); ROUTE_SHOW_MAP.register(); 

After including all the Javascript files (which can register routes) I call Router.getInstance (). init ();

When I make an ajax request somewhere (manually) for which a route exists, I call ROUTE_NAME.executed () to set the identifier and register it with the history.

In addition, I have an observer that updates some links that are used for direct translations, whenever the location hash is changed using executed ()

+7
source share
6 answers

This is the same situation as the update, so you must reuse this system.

Basically, your hash should contain enough information to rebuild the entire page. Of course, sometimes you need to save some user data in order to rebuild the page. What localStorage for (userData for IE)

+8
source

If you have not added your events through the API that tracks them (e.g. jQuery, see http://api.jquery.com/clone#true ), you will not be able to think about the events that have been added so that they serialize / save.

If you made the unlikely choice of using DOM user data, you'll also need setUserData () to serialize any user DOM data (or again, a library such as jQuery to track it for you).

+2
source

How about getting everyone in the iframe and mirror all the fragments of the url in the parent, and then act on the iframe. Perhaps there is a cross-site scripting problem.

It is very difficult that you do otherwise because the browser caches - it decides whether to load from memory - not you. Therefore, if the above is not an option, the only way you will create it is with a browser extension that listens for the tab button event and acts accordingly.

+2
source

Have you looked at the jQuery history plugin ? I know that in another post you mentioned that jQuery is not an option, but you can imitate their approach.

I am not an expert on this issue, but due to various browser implementations, I believe that this is not the case to get a working cross browser.

Main site: http://tkyk.github.com/jquery-history-plugin/#

Demo page: http://www.serpere.info/jquery-history-plugin/samples/ajax/

+1
source

What you want is almost impossible, you could do it if you used a library like jquery to create events for your page like brettz9, but in your case you use google maps and other external libraries, so that’s not an option, Here you can find out which page you are on and run javascript that initializes this page as if it was loaded for the first time. To do this, you need to track not only the html of the page, but also the javascripts that execute when the page loads.

+1
source

The only way I know is to trick the browser into believing that every worthwhile event is a new page. This can be done by loading a new page using window.location or submitting the form using get (= query string). The new location or form data should contain everything necessary to display the correct information. This has its drawbacks - here is my opinion:

Good:

  • back and forth buttons work
  • You can view bookmarks of your data.
  • with careful use of query string data, it offers an API for your system

Poorly:

  • each standing event should go through page loading.
  • can't use ajax
  • you need to develop a way to encode each state of your system in the form of a query string.
0
source

All Articles