Cross-browser jquery ajax history with window.hist

2019-01-30 04:03发布

I want to implement a navigation history using jQuery and AJAX in a cross-browser manner. My approach is to use window.history.pushState and fall back to a hash url /#!/url in browsers that do not support window.history.pushState.

For example:

<a href="/home">home</a>
<a href="/about">about</a>
<a href="/contact">contact</a>

On browsers that support window.history.pushState, clicking on one of these links should change address without page refresh to http://domain.com/home, http://domain.com/about etc. When the browser does not support window.history.pushState, it should use a fragment identifier, i.e: http://domain.com/#!/home, http://domain.com/#!/about.


Update: Based on the feedback here I have implemented Ajax SEO (git) that uses jQuery Address for HTML5 History API with old browser fallback to /#!/url.

3条回答
家丑人穷心不美
2楼-- · 2019-01-30 04:37

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 history
Backbone.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/

查看更多
神经病院院长
3楼-- · 2019-01-30 04:42

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.

查看更多
三岁会撩人
4楼-- · 2019-01-30 04:50
// 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;
}
查看更多
登录 后发表回答