I am trying to store the state of a page in the hash. This works in IE and FF but in Chrome it does not seem to do anything
$(document).ready(function()
{
window.onbeforeunload = savePageState;
});
function savePageState()
{
var currentTab = _tabbing.getCurrentTab();
var mapState = _mapAdapter.getMapState();
window.location.hash =
'reload=' + currentTab +
'&mapType=' + mapState.MapType.getName() +
'&lat=' + mapState.Latitude +
'&long=' + mapState.Longitude +
'&zoom=' + mapState.ZoomLevel;
return;
}
Is there a quirk in Chrome that prevents me from updating the hash? Is there a better way to go about saving the pages state? Its only for the back button that it needs to be saved.
I'd recomend that you use the jQuery BBQ plugin, which manages the hash for you.
$.bbq.pushState({
reload: currentTab,
mapType: mapState.MapType.getName(),
lat: mapState.Latitude,
long: mapState.Longitude,
zoom: mapState.ZoomLevel
});
BBQ handles merging the hash, so it will not overwrite other parameters. For example, #fun=yes becomes #fun=yes&reload=tab&...
Next, you can listen for changes to the hash:
$(window).bind('hashchange', function(e) {
var params = e.getState();
doStuff(params.lat, params.long);
});
While BBQ was nice, it did not entirely solve my problem. For it to work in Chrome / Safari, you need to update the hash before the onbeforeunload event. Part of the requirement however made it so that was the only real time that I could save the state of the page.
I came up with a solution, using both of the other answers here, using pushState and BBQ. I thought I would post it incase anyone else has the same issue I did.
function BackButtonState(saveStateCallback, pageLoadCallback)
{
var executePopStateCounter = null;
var myData = {};
var browserCanPushState = history.pushState ? true : false;
window.onbeforeunload = saveStateCallback;
if (browserCanPushState)
{
//The version of safari this was tested on (5.0.3) uses an outdated version of
//Webkit that has a bug where popstate is not called on the first page load.
//This is a hacky work around until the problem is fixed.
var agt = navigator.userAgent.toLowerCase();
if (agt.indexOf("safari") != -1)
{
executePopStateCounter = setTimeout(pageLoadCallback, 500);
};
window.onpopstate = function(popEvent)
{
clearTimeout(executePopStateCounter);
if (popEvent.state != null)
{
myData = popEvent.state;
}
pageLoadCallback();
}
}
else
{
$(document).ready(pageLoadCallback);
}
this.savePageState = function(state)
{
if (browserCanPushState)
{
history.pushState(state, 'BackButtonState');
}
else
{
$.bbq.pushState(state);
}
}
this.getState = function(item)
{
if (browserCanPushState)
{
return myData[item];
}
else
{
return $.bbq.getState(item);
}
}
this.deserializeSortList = function(sortArrays)
{
var sortList = [];
$.each(sortArrays, function(index, pair)
{
sortList.push([parseInt(pair[0]), parseInt(pair[1])]);
});
return sortList;
}
}
To use this, you do something like:
function saveState()
{
var myData = { bananas: 'are tasty' };
_backButton.saveState(myData);
}
function pageSetup()
{
//Do normal $(document).ready() stuff here
var myOpinionOnFruit = _backButton.getState('bananas');
}
var _backButton = new BackButtonState(saveState, pageSetup);
This is not guarenteed to be bug free, and I am unhappy with the hack I had to do for Safari. I just wanted to post this before I forgot.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With