How do I actually use history.js on my site

pappley picture pappley · Apr 1, 2013 · Viewed 31.3k times · Source

I've read all the posts about history.js on stackoverflow including, this, this and this and at looked the source code but as a newcomer to javascript/jquery I'm having trouble figuring out how to actually implement to have html 5 history support and fallback to support html4 browsers such as ie8/9. As I can appreciate the UX benefits from presenting consistent URL's as much as possible, how this solves deep linking and allows for bookmarking I want to implement but I get a bit lost when trying to actually use this on my site.

After adding history.js script to my page

The code to modify as I undertand it is:

    function(window,undefined){

    // Prepare
    var History = window.History; // Note: We are using a capital H instead of a lower h
    if ( !History.enabled ) {
         // History.js is disabled for this browser.
         // This is because we can optionally choose to support HTML4 browsers or not.
        return false;
    }

    // Bind to StateChange Event
    History.Adapter.bind(window,'statechange',function(){ // Note: We are using statechange instead of popstate
        var State = History.getState(); // Note: We are using History.getState() instead of event.state
        History.log(State.data, State.title, State.url);
    });

    // Change our States
    History.pushState({state:1}, "State 1", "?state=1"); // logs {state:1}, "State 1", "?state=1"
    History.pushState({state:2}, "State 2", "?state=2"); // logs {state:2}, "State 2", "?state=2"
    History.replaceState({state:3}, "State 3", "?state=3"); // logs {state:3}, "State 3", "?state=3"
    History.pushState(null, null, "?state=4"); // logs {}, '', "?state=4"
    History.back(); // logs {state:3}, "State 3", "?state=3"
    History.back(); // logs {state:1}, "State 1", "?state=1"
    History.back(); // logs {}, "Home Page", "?"
    History.go(2); // logs {state:3}, "State 3", "?state=3"

})(window);

Is the //Change our states where all new code goes as this code just gives examples of the history controls?

Or should I be writing my own code in place of this whole code block (I use jquery to help me at this point, given my newness to coding).

I was reading this article about dynamic content loading and trying to implement on my site(I can get this code to work but I know that it won't play well in ie8/9), but am having trouble trying to figure out how to combine with history.js

Aslo, secondarily, I'm trying to figure out how history.js plays with modernizr?

Is it a replacement for modernizr.history (where it does the testing and if there is no support for .js falls back to typical page loading) or would it function like this:

if (Modernizr.history) {
   //Code goes here that works if it's HTML 5 Browser with .history support? I know some HTML5 browsers deal with .history oddly (read buggy) so what happens in those cases?
} else {
   //code from above goes here? with function(window, undefined){...etc...  ?
}

Answer

Robert Hoffmann picture Robert Hoffmann · Apr 1, 2013

Just adding history support to your site won't help you in any way unless you actually have functions in place that make use of it.

As far as modernize goes it just tells you if history is supported on the current browser and if you take action x else action y

Ok so this is how history would work:

Consider history.js kind of like a macro recorder. A client clicks something and you push some variables that you associate with a made up or real url:

Client clicks a search for example, you call:

function search(params) {
  // record your current UI position
  // data (to save), title (to set on page), url (to set on page)
  History.pushState({ params: params }, "Search", "?search");


   // now run whatever should happen because client triggered search()
}

And now when the client clicks the back button, you can get the previously saved state to do something with it. Since the client hits his backbutton, it will trigger statechange. And since you are subscribed to that event, you can determine what state you previously saved and call functions to change the UI accordingly.

// Bind to StateChange Event
History.Adapter.bind(window, 'statechange', function() {
  var State = History.getState();

  // returns { data: { params: params }, title: "Search": url: "?search" }
  console.log(State); 

  // or you could recall search() because that's where this state was saved
  if (State.url == "?search") {
    search(data.params);
  }
});

That pretty much sums it up. Client triggers a function, you assign a state/url, and when client clicks back you look at your previous state and run functions depending on if you want to restore UI or other.

This can all quickly become complicated and tricky code and I don't see what else there is to explain, so unless you just got the AHA! and now know what to do, I'd just forget about this stuff for now.

There is absolutely nothing automatic going on here aside for saving/restoring states, everything else in your application will need to be hand-coded to take into account what happens if a state changes.

Also deep linking has nothing to do with these things. Your application has to have the capacity to initialize itself and display specific UI elements uniquely based on calling it directly via a url. History is solely for state management when users are already using your application, so you are able to control what happens when they hit the back/forward button.

And anything that happens via JS, will give you zero benefits as far as search engines are concerned as they don't care about js and will just index the raw text of you page. So if you want search engine compatible deep linking, you need server side code that renders you UI to a specific state depending on requested URL.