web-dev-qa-db-fra.com

Puis-je empêcher history.popstate de se déclencher lors du chargement initial de la page?

Je travaille sur un site qui sert du contenu via AJAX.

Si vous cliquez sur un élément du menu, une div de contenu est mise à jour avec $.get réponse, rien d'extraordinaire.

J'implémente history.pushState pour permettre la navigation avec le bouton Précédent/Suivant du navigateur.

J'ai les éléments suivants pour charger du contenu sur la navigation dans l'historique:

$(function() {
    $(window).bind("popstate", function() {
        $.getScript(location.href); 
    });
});

Le problème est que lorsqu'une page est chargée pour la première fois, cette fonction ne $.getScript pour que la page se charge à nouveau immédiatement. La première fois que la page est chargée, elle affiche la vue HTML initiale, puis au deuxième chargement, elle rend la vue JS, car il s'agit d'une demande JS.

Comment pourrais-je empêcher cet événement de se déclencher sur les pages contenant des requêtes HTML?

25
jassa

En utilisant l'API native HTML5 History, vous allez rencontrer des problèmes, chaque navigateur HTML5 gère l'API un peu différemment, vous ne pouvez donc pas la coder une seule fois et vous attendre à ce qu'elle fonctionne sans implémenter de solutions de contournement. History.js fournit une API inter-navigateur pour l'API HTML5 History et une option hashchange de secours pour les navigateurs HTML4 si vous souhaitez emprunter cette voie.

Pour mettre à niveau votre site Web vers une application RIA/Ajax, vous pouvez utiliser cet extrait de code: https://github.com/browserstate/ajaxify

Qui fait partie de l'article plus long Intelligent State Handling qui va dans les explications sur le hashbang, les hachages et l'api de l'historique html5.

Faites-moi savoir si vous avez besoin d'aide :).

37
balupton

Vous devez obtenir l'événement.

// Somewhere in your previous code
if (history && history.pushState) {
  history.pushState({module:"leave"}, document.title, this.href);
}


$(window).bind("popstate", function(evt) {
  var state = evt.originalEvent.state;
  if (state && state.module === "leave") {
    $.getScript(location.href);
  }
});
23
mech

Lorsque l'événement popstate est déclenché au chargement de la page, il n'aura pas de propriété d'état dans l'objet événement. Cela vous permet de vérifier si l'événement est déclenché pour un chargement de page ou non.

window.onpopstate = function (event) {
  if (event.state) {
    // do your thing
  } else {
    // triggered by a page load
  }
}
8

Lors du premier chargement du navigateur, il déclenche toujours un événement popstate. Vous devez donc déterminer si ce popstate est le vôtre ou non.

Lorsque vous effectuez votre pushState, assurez-vous que vous disposez d'un objet d'état. De cette façon, vous pouvez le vérifier plus tard.

Ensuite, sur le gestionnaire popstate, vérifiez l'objet d'état :)

$(function() {
    $(window).bind("popstate", function(data) {
        if (data.state.isMine)
            $.getScript(location.href); 
    });
});

// then add the state object
history.pushState({isMine:true},title,url);

Faites-moi savoir si vous avez besoin d'aide :)

4
sydlawrence

Je l'utilise pour changer l'adresse de la barre et enregistrer l'état actuel, y compris le corps html actuel, et je le recharge en cliquant sur le bouton de retour sans aucun autre appel ajax. Tout est enregistré dans votre navigateur:

  1. $(document).ajaxComplete(function(ev, jqXHR, settings) {
    
        var stateObj = { url: settings.url, innerhtml: document.body.innerHTML };
        window.history.pushState(stateObj, settings.url, settings.url);
    });
    
    
    window.onpopstate = function (event) {
        var currentState = history.state;
        document.body.innerHTML = currentState.innerhtml;
    };
    
0
ghooz