Cross-browser jquery ajax history with window.history.pushState and fallback Cross-browser jquery ajax history with window.history.pushState and fallback jquery jquery

Cross-browser jquery ajax history with window.history.pushState and fallback


// Assuming the path is retreived and stored in a variable 'path'if (typeof(window.history.pushState) == 'function') {    window.history.pushState(null, path, path);} else {    window.location.hash = '#!' + path;}


Something i've been using with fallback hash URL's:

History = History || {};History.pathname = null;History.previousHash = null;History.hashCheckInterval = -1;History.stack = [];History.initialize = function () {    if (History.supportsHistoryPushState()) {        History.pathname = document.location.pathname;        $(window).bind("popstate", History.onHistoryChanged);    } else {        History.hashCheckInterval = setInterval(History.onCheckHash, 200);    }};History.supportsHistoryPushState = function () {    return ("pushState" in window.history) && window.history.pushState !== null;};History.onCheckHash = function () {    if (document.location.hash !== History.previousHash) {        History.navigateToPath(document.location.hash.slice(1));        History.previousHash = document.location.hash;    }};History.pushState = function (url) {    if (History.supportsHistoryPushState()) {        window.history.pushState("", "", url);    } else {        History.previousHash = url;        document.location.hash = url;    }    History.stack.push(url);};History.onHistoryChanged = function (event) {    if (History.supportsHistoryPushState()) {        if(History.pathname != document.location.pathname){            History.pathname = null;            History.navigateToPath(document.location.pathname);        }    }};History.navigateToPath = function(pathname) {    History.pushState(pathname);    // DO SOME HANDLING OF YOUR PATH HERE};

You could bind your click events to this with:

$(function(){    $("a").click(function(){        var href = $(this).attr('href');        History.navigateToPath( href )        return false;    });});

If you need some more explanation on this example i'll be glad to hear it.


EDIT

Please see my other answer.


It has been a while since my original answer and I would now suggest using Backbone.

An implementation could be:

// First setup a router which will be the responder for URL changes:var AppRouter = Backbone.Router.extend({  routes: {    "*path": "load_content"  },  load_content: function(path){    $('#content').load('/' + path);  }});var appRouter = new AppRouter;// Then initialize Backbone's historyBackbone.history.start({pushState: true});

Excerpt from the documentation:

To indicate that you'd like to use HTML5 pushState support in your application, use Backbone.history.start({pushState: true}). If you'd like to use pushState, but have browsers that don't support it natively use full page refreshes instead, you can add {hashChange: false} to the options.

And now every time Backbone.history.navigate is called, the AppRouter will perform an AJAX load of the path into the #content div.

To handle all links with AJAX you could use the following:

$("a").on('click', function(event){    event.preventDefault();    Backbone.history.navigate( event.currentTarget.pathname, {trigger: true} )});

Take note of the {trigger: true} which causes the handler in the router to be called (otherwise only from url changes).

Fiddle with example code: http://jsfiddle.net/koenpunt/pkAz7/1/