31 votes

Historique ajax jquery multi-navigateur avec window.history.pushState et fallback

Je veux mettre en œuvre un historique de la navigation à l'aide de jQuery et AJAX cross-navigateur de la manière. Mon approche est d'utiliser window.history.pushState et de revenir à un hash de l'url /#!/url dans les navigateurs qui ne prennent pas en charge window.history.pushState.

Par exemple:

<a href="http://stackoverflow.com/home">home</a>
<a href="http://stackoverflow.com/about">about</a>
<a href="http://stackoverflow.com/contact">contact</a>

Pour les navigateurs qui supportent window.history.pushState, en cliquant sur l'un de ces liens doivent changer d'adresse sans rafraichissement de la page pour http://domain.com/home, http://domain.com/about etc. Lorsque le navigateur ne prend pas en charge window.history.pushState, il doit utiliser un identificateur de fragment, j'.e: http://domain.com/#!/à la maison, http://domain.com/#!/à propos de.


Mise à jour: sur la Base des commentaires ici, j'ai mis en œuvre Ajax SEO (git) qui utilise jQuery Adresse pour HTML5 Histoire de l'API du vieux navigateur de secours d' /#!/url.

22voto

Ben Lee Points 25935
// 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;
}

6voto

Koen. Points 3570

Quelque chose que j'utilise avec les URL de hachage de secours:

 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

};
 

Vous pouvez associer vos événements de clic à ceci avec:

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

Si vous avez besoin de plus d'explications sur cet exemple, je serai heureux de l'entendre.


ÉDITER

Veuillez voir mon autre réponse.

4voto

Koen. Points 3570

Il a été un moment depuis que ma réponse originale à cette question et je voudrais maintenant vous suggérons d'utiliser épine Dorsale.

Une mise en œuvre pourrait être:

// 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});

Extrait de la documentation:

Pour indiquer que vous souhaitez utiliser HTML5 pushState de soutien dans votre application, utilisez Backbone.history.start({pushState: true}). Si vous souhaitez utiliser pushState, mais ont les navigateurs qui ne supportent pas nativement l'utilisation complète de la page se rafraîchit au lieu de cela, vous pouvez ajouter {hashChange: false} pour les options.

Et maintenant à chaque fois qu' Backbone.history.navigate est appelée, l' AppRouter va effectuer une requête AJAX charge de la trajectoire dans l' #content div.

Pour gérer tous les liens avec l'AJAX, vous pouvez utiliser les éléments suivants:

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

Prendre note de l' {trigger: true} ce qui provoque le gestionnaire dans le routeur d'être appelé (autrement que de changements de l'url).

Jouer avec un exemple de code: http://jsfiddle.net/koenpunt/pkAz7/1/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X