24

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...  ?
}
Community
  • 1
  • 1
pappley
  • 379
  • 1
  • 3
  • 12

1 Answers1

30

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.

brg
  • 7,332
  • 8
  • 44
  • 60
Robert Hoffmann
  • 2,308
  • 17
  • 26
  • Yes, that's my question, where do those functions go and how do they make use of history.js. I'm asking when writing those functions what do I have to keep in mind, where do they go and how do they communicate with history.js behind the scenes – pappley Apr 01 '13 at 14:52
  • History is something I see more being used in single page ajax applications, for example in the bind part above you would have something like if state.url == this, then execute that, else execute something else. It allows you to dynamically load different sections of a single page application depending on a URL. But all this can be pretty complicated stuff. And saying you are new to js/jQuery I'm a bit in doubt you even need these kind of advanced features. Explain what you would like to accomplish IF you had history support. – Robert Hoffmann Apr 01 '13 at 15:02
  • Sure. I'm creating a website in which deeper levels share a lot of common markup. Thus, I'd like to pull in just the changing content. (A lot of this would happen in sliding panels. I would load content off screen then slide it on screen on a click event). I think it creates a much more intuitive user experience if content that is common is not continually reloaded. However, I would need to provide the ability for users to bookmark or share site links, navigate with the browser back/forward button as these are accepted user practices. As I understand it this is exactly what history.js is for. – pappley Apr 01 '13 at 15:49
  • 1
    This is actually revelatory, thank you. Now that you show it, it seems doable. However, I'm still confused as to how it works with modernizr. I understand the basic use of modernizr but in this case is it still necessary. Would I still test for history, apply my code, then fallback to history.js and essentially supply the same code modified to work within the history.js framework. It seems a bit odd to use modernizr in this case, or is it with the intention that less and less browsers will need to call history.js in the future as my audience updates their technology – pappley Apr 02 '13 at 01:36
  • 1
    @Robert Google crawler does run JS now, see here: http://googlewebmastercentral.blogspot.com.au/2014/05/understanding-web-pages-better.html – andrewb Oct 07 '14 at 21:53