I've implemented History.js on a local test application. Everything seems to work, however if I press the back button in the browser, the previous content does not get restored.
Do I actually have to load the content manually again (i.e. make another ajax call) when user presses the back button? Then how does github do it? I see they don't make another ajax call when clicking back button in the code tree.
Here is my code:
History.Adapter.bind(window,'statechange',function()
{
var State = History.getState();
History.log(State.data, State.title, State.url);
});
$('a').each(function(index, link) {
if ($(link).attr('data-ajax-disabled') != 'true') {
$(link).click(function(event)
{
var clips = $(this).attr('data-ajax-clips') || '';
$.ajax($(this).attr('href'),
{
data: {_clips:clips},
success: function(data)
{
var data = $.parseJSON(data);
History.pushState({state:1}, data.title || document.title, 'http://127.0.0.1/site/www/');
$.each(data.clips, function(key, val)
{
$(key).replaceWith(val);
});
}
});
return false;
});
}
});
data.clips is a json array which contains id's of html objects as key and the actual html content as value. For example
'#header' => 'content in header div'
As noted, the replacement works fine. I output a random number in the header. Every click on a link spits out another random number in the header. However, if I push the back button the number stays the same, only the title will be restored (also random number).
Ok I got it, also thanks to Tobias Cohen for the hint.
One has to store the loaded data in the history object (State.data). First let's see how the statechange callback changed:
History.Adapter.bind(window, 'statechange', function()
{
var State = History.getState();
$.each(State.data.clips, function(key, val)
{
$(key).replaceWith(val);
});
History.log(State.data, State.title, State.url);
});
As you can see, on each statechange I can access State.data.clips and replace the html content.
NOTE: A statechange does also happen when calling History.pushState(). That means in my initial question the second code snippet is wrong in the fact that I do the content manipulation in there. There's no need for it. Just call History.pushState() and do any content manipulation within the statechange callback.
So for completeness, this is how I push the clips into the history object:
History.pushState({state:1, clips:data.clips}, data.title || document.title, 'http://127.0.0.1/site/www/');