238 votes

Comment détecter si l'URL a changé après un hachage en JavaScript ?

Comment puis-je vérifier si une URL a changé en JavaScript ? Par exemple, des sites Web comme GitHub, qui utilisent AJAX, ajouteront des informations sur la page après un symbole # pour créer une URL unique sans recharger la page. Quel est le meilleur moyen de détecter si cette URL a changé ?

  • Est-ce que le onload L'événement est rappelé ?
  • Y a-t-il un gestionnaire d'événement pour l'URL ?
  • Ou faut-il vérifier l'URL toutes les secondes pour détecter un changement ?

1 votes

Pour les futurs visiteurs, une nouvelle réponse de @aljgom de 2018 est la meilleure solution : stackoverflow.com/a/52809105/151503

215voto

aljgom Points 1116

Je voulais être capable d'ajouter locationchange des écouteurs d'événements. Après la modification ci-dessous, nous serons en mesure de le faire, comme ceci

window.addEventListener('locationchange', function(){
    console.log('location changed!');
})

En revanche, window.addEventListener('hashchange',()=>{}) ne se déclencherait que si la partie après un hashtag dans une url change, et window.addEventListener('popstate',()=>{}) ne fonctionne pas toujours.

Cette modification, similaire à Réponse de Christian modifie l'objet historique pour y ajouter certaines fonctionnalités.

Par défaut, avant ces modifications, il y a une popstate mais il n'y a pas d'événement pour pushstate et replacestate .

Ces trois fonctions sont modifiées de manière à ce qu'elles déclenchent toutes une fonction personnalisée. locationchange que vous pouvez utiliser, et aussi pushstate et replacestate si vous voulez les utiliser.

Voici les modifications :

history.pushState = ( f => function pushState(){
    var ret = f.apply(this, arguments);
    window.dispatchEvent(new Event('pushstate'));
    window.dispatchEvent(new Event('locationchange'));
    return ret;
})(history.pushState);

history.replaceState = ( f => function replaceState(){
    var ret = f.apply(this, arguments);
    window.dispatchEvent(new Event('replacestate'));
    window.dispatchEvent(new Event('locationchange'));
    return ret;
})(history.replaceState);

window.addEventListener('popstate',()=>{
    window.dispatchEvent(new Event('locationchange'))
});

Note :

Nous créons un fermeture , old = (f=>function new(){f();...})(old) remplace old avec un new qui contient le précédent old enregistré en son sein ( old n'est pas exécuté pour le moment, mais il le sera à l'intérieur de l'application new )

137voto

phihag Points 89765

Dans les navigateurs modernes (IE8+, FF3.6+, Chrome), vous pouvez simplement écouter l'icône hashchange événement sur window .

Dans certains anciens navigateurs, vous avez besoin d'un timer qui vérifie continuellement location.hash . Si vous utilisez jQuery, il y a une plugin qui fait exactement cela.

156 votes

Si je comprends bien, cela ne fonctionne que pour le changement de la partie après le signe # (d'où le nom de l'événement) ? Et non pour le changement complet de l'URL, comme semble l'impliquer le titre de la question.

15 votes

@NPC Un gestionnaire pour le changement d'URL complet (sans balise d'ancrage) ?

0 votes

Vous avez rarement besoin d'événements de temporisation : utilisez les événements de la souris et du clavier pour la vérification.

98voto

window.onhashchange = function() { 
     //code  
}

window.onpopstate = function() { 
     //code  
}

ou

window.addEventListener('hashchange', function() { 
  //code  
}

window.addEventListener('popstate', function() { 
  //code  
}

avec jQuery

$(window).bind('hashchange', function() {
     //code
});

$(window).bind('popstate', function() {
     //code
});

79voto

Cristian Points 1272

EDIT après quelques recherches :

Il semble que j'ai été trompé par la documentation présente sur Mozilla docs. Le site popstate (et sa fonction de rappel onpopstate ) sont non déclenché chaque fois que le pushState() ou replaceState() Par conséquent, la réponse originale ne s'applique pas dans tous les cas.

Il existe toutefois un moyen de contourner ce problème en monkey-Parcheando les fonctions selon @alpha123 :

var pushState = history.pushState;
history.pushState = function () {
    pushState.apply(history, arguments);
    fireEvents('pushState', arguments);  // Some event-handling function
};

Réponse originale

Étant donné que le titre de cette question est " Comment détecter un changement d'URL "La réponse, lorsque vous voulez savoir quand le chemin complet change (et pas seulement l'ancre de hachage), est que vous pouvez écouter la commande popstate événement :

window.onpopstate = function(event) {
  console.log("location: " + document.location + ", state: " + JSON.stringify(event.state));
};

Référence pour popstate dans Mozilla Docs

Actuellement (janvier 2017), il y a le soutien à l'État providence de 92 %. de navigateurs dans le monde entier.

52voto

Pantelis Points 2032

Avec jquery (et un plug-in) vous pouvez faire

$(window).bind('hashchange', function() {
 /* things */
});

http://benalman.com/projects/jquery-hashchange-plugin/

Sinon, oui, vous devez utiliser setInterval et vérifier si l'événement de hachage (window.location.hash) a changé.

Mise à jour ! Un simple projet

function hashHandler(){
    this.oldHash = window.location.hash;
    this.Check;

    var that = this;
    var detect = function(){
        if(that.oldHash!=window.location.hash){
            alert("HASH CHANGED - new has" + window.location.hash);
            that.oldHash = window.location.hash;
        }
    };
    this.Check = setInterval(function(){ detect() }, 100);
}

var hashDetection = new hashHandler();

0 votes

Puis-je détecter le changement de (window.location) et le gérer ? (sans jquery)

7 votes

Vous pouvez @BergP, en utilisant le simple listener javascript : window.addEventListener("hashchange", hashChanged);

1 votes

Un intervalle de temps aussi court est-il bon pour l'application ? En d'autres termes, le navigateur n'est-il pas trop occupé à exécuter detect() fonction ?

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