2009-10-19 12 views
33

J'essaye de recharger la page courante avec le hash différent d'url, mais cela ne fonctionne pas comme prévu.Comment forcer une page à recharger si tout ce qui a été modifié dans l'URL est un hachage?

(Précision comment je veux que cela fonctionne. Recharger la page, puis faites défiler jusqu'à la nouvelle hachage)

Approche # 1:

window.location.hash = "#" + newhash; 

Seuls les rouleaux à ce point d'ancrage sans recharger la page.

Approche # 2:

window.location.hash = "#" + newhash; 
window.location.reload(true); 

fonctionne Kinda mais premiers rouleaux à l'ancre, puis la page recharge, puis défile à l'ancre à nouveau.

Approche # 3:

window.location.href = window.location.pathname + window.location.search + "&random=" + Math.round(Math.random()*100000) + "#" + newhash; 

Works, mais je préfère ne pas ajouter des ordures au hasard à l'URL.

Existe-t-il une meilleure solution?

Répondre

30

Retirez l'ancre que vous allez naviguer, puis utilisez l'approche # 2? Comme il n'y a pas d'ancre, la définition du hachage ne doit pas faire défiler la page.

+5

Au début, je ne comprenais pas que vous vouliez le retirer de DOM. Cela fonctionne, merci. – serg

+1

Si vous voulez garder l'affichage plus intact, il suffit de supprimer son attribut 'name' ou' id' pour cela - le noeud lui-même peut rester. – ecmanaut

2

Il devrait être prévu que #foo défilera jusqu'à l'ancre de l'ID, "foo". Si vous voulez utiliser l'approche n ° 1 et la recharger, cette approche pourrait fonctionner.

if (Object.defineProperty && Object.getOwnPropertyDescriptor) { // ES5 
    var hashDescriptor = Object.getOwnPropertyDescriptor(location, "hash"), 
    hashSetter = hashDescriptor.set; 
    hashDescriptor.set = function (hash) { 
     hashSetter.call(location, hash); 
     location.reload(true); 
    }; 
    Object.defineProperty(location, "hash", hashDescriptor); 
} else if (location.__lookupSetter__ && location.__defineSetter__) { // JS 
    var hashSetter = location.__lookupSetter__("hash"); 
    location.__defineSetter__("hash", function (hash) { 
     hashSetter.call(location, hash); 
     location.reload(true) 
    }); 
} 
+0

Je ne pouvais pas le faire fonctionner. Même s'il est sacré $%^& :) – serg

+0

Je ne l'ai jamais testé mais il devrait fonctionner dans tous les principaux navigateurs (sans compter IE <8) et si ce n'est pas le cas, c'est probablement parce que IE ne permettra pas de redéfinir le descripteur location.hash pour des "raisons de sécurité" bien que ce soit –

+0

cette approche a fonctionné pour moi! bizarre – fabio

3

J'ai eu une fonction JQuery qui a tiré sur $(document).ready() qui a détecté s'il y avait un hachage ajouté à l'URL dans mon cas, donc je gardé cette fonction même et puis juste utilisé un rechargement de force chaque fois qu'un changement de hachage était détectée:

$(window).on('hashchange',function(){ 
    window.location.reload(true); 
}); 

Alors mon autre fonction -

$(document).ready(function() { 
    var hash = window.location.hash;  
    if(hash) { 
      //DO STUFF I WANT TO DO WITH HASHES 
    } 
}); 

Dans mon cas, il était très bien pour UX - pourrait ne pas être bon pour les autres.

+1

L'événement prêt de jQuery ne se déclenchera pas lorsque 'fenêtre.location = "#myHash" 'est exécuté, ce qui serait le point dans cette question, je crois. Toutefois, ce code est utile pour le chargement de contenu dynamique, par exemple, si la page est rechargée. – JoeBrockhaus

0

Une autre option consiste à supprimer le hachage et le stocker dans le stockage de session pour récupérer le reload:

var newUrl = location.href + '#myHash'; 
var splitUrl = newUrl.split('#'); 
newUrl = splitUrl[0]; 
if (splitUrl[1]){ 
    sessionStorage.savedHash = splitUrl[1]; 
} 
location.href = newUrl; 

puis en haut de votre page, vous pouvez avoir le code suivant:

var savedHash = sessionStorage.savedHash; 
if (savedHash){ 
    delete sessionStorage.savedHash; 
    location.hash = savedHash; 
}