JQuery & history.js back button not working
Asked Answered
C

2

15

I'm using history.JS (latest) with Jquery (latest) to load and replace just a portion of a website, this is all working, currently I'm only trying to get it working in modern browsers so I'm not fiddling with the hash changes.

Everything seems to work, however when I click the back button on the browser (latest FF & Chrome) the page does not change (although the url and title do change). I've had a google and a look on here but I can't see what is happening.

Looking on stack overflow I found this page: Restoring content when clicking back button with History.js which seems to be asking a similar question. I've add the loaded contents of the #left_col (which is the div being replaced) to the state data, but I'm not really sure where to go from there, I know I need to reload that data when the state changes, but I can't see how.

var History = window.History; 
var origTitle = document.title;
if ( !History.enabled ) {
    return false;
}
    
History.Adapter.bind(window,'statechange',function(){ 
    var State = History.getState();     
    History.log(State.data, State.title, State.url);
});

$('.ajaxload').live("click", function() {
    History.pushState({state:1,leftcol:$('#left_col').html()}, origTitle, $(this).attr("href"));
    $('#left_col').load($(this).attr("rel"));
    return false;
});

I'd really appreciate any help!

update:

I managed to get the page to change on the user clicking back, but it doesn't load the right state (it seems to go two states back rather than one), the code I've added to the above code is:

window.addEventListener('popstate', function(event) {
    var State = History.getState(); 
    $('#left_col').html(State.data.leftcol);
});
Connolly answered 21/6, 2012 at 20:41 Comment(0)
C
10

It turns out I needed to update the page on statechange using History.js, not poState as I'd thought. below is my full (and working) code for anyone who may be having the same issue:

    var History = window.History;
    var origTitle = document.title;

    if ( !History.enabled ) { return false; }
    History.pushState({state:$(this).attr('data-state'),leftcol:$('#left_col').html()}, origTitle, $(this).attr("href"));           // save initial state to browser history

    function updateContent(data) {
        if(data == null) return;                    // check if null (can be triggered by Chrome on page load)
        $('#left_col').html(data);              // replace left col with new (or old from history) data
        History.pushState({state:$(this).attr('data-state'),leftcol:$('#left_col').html()}, origTitle, $(this).attr("href"));           // save this state to browser history
    }

    History.Adapter.bind(window,'statechange',function(){           // use this NOT popstate (history.JS)
        var State = History.getState();
        //History.log(State.data, State.title, State.url);
        updateContent(State.data.leftcol);                                          // call update content with data for left col from saved state
    });

    $('.ajaxload').live("click", function() {                                   // attach click event, get html and send it to updateContent
        $.get($(this).attr("rel"), updateContent);
        return false;
    });
Connolly answered 25/6, 2012 at 21:54 Comment(3)
I found another problem. 1. on main page > click on link to page A 2. on page A > F5 reload the page > click back 3. it does not go back. you have to click it twice. How to fix twice click?Mabe
Hi, I'm not sure about that I'm afraid.Connolly
This answer is outdated, see github.com/browserstate/history.js/issues/47 for use of state.internalAtman
T
0

You are correct when you say that you need to reload the data when the state changes, in that you will have to have the javascript undo the changes made or render the contents again from the original state.

This will probably better suit your agenda: https://github.com/thorsteinsson/jquery-routes

Edit:

You might also consider using backbone.js (http://backbonejs.org/) as it will help you create structure and abstract code in a way that makes it easier to understand what needs to be done.

Backbone comes with it's own url router and so called views.

Twopenny answered 21/6, 2012 at 20:50 Comment(4)
Thanks, I am really keen to stick with History.JS as I want to use it for compatibility with older browsers once I've got it fully working on the modern ones. I just don't understand what event or trigger I need to use to load the data from the old state back into the page.Connolly
I'm setting this up on an existing site, basically my aim is to save on slower page loads when moving between pages within a section of the site by swapping out an image and related comments. I'm not creating an app or starting from scratch so I'm really just looking to fix what is there.Connolly
I don't think compatibility is an issue with either backbone or jquery-routes. If you want to stick with History.js then you'll have to check the url on state change and undo the changes if the url same as the original url.Twopenny
Yes that's right, that's what I'm trying to do, but I just don't know how to.Connolly

© 2022 - 2024 — McMap. All rights reserved.