2009-10-19 3 views
33

Ich versuche, aktuelle Seite mit anderen URL-Hash zu laden, aber es funktioniert nicht wie erwartet.Wie erzwinge eine Seite neu zu laden, wenn alles, was in URL geändert wurde, Hash ist?

(Klärung, wie ich will es an die Arbeit. Aktualisieren Sie die Seite und dann auf den neuen Hash scrollen)

Ansatz # 1:

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

Nur Rollen zu diesem Anker ohne das Nachladen Seite.

Ansatz # 2:

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

Kinda funktioniert, aber es erste Rollen auf den Anker, neu lädt dann die Seite, dann rollt wieder auf den Anker.

Ansatz # 3:

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

Werke aber ich würde lieber nicht zufällig Müll auf die URL hinzuzufügen.

Gibt es eine bessere Lösung?

Antwort

30

Entfernen Sie den Anker, zu dem Sie navigieren möchten, und verwenden Sie dann Approach # 2? Da kein Anker vorhanden ist, sollte beim Festlegen des Hash-Werts nicht auf der Seite geblättert werden.

+5

Zuerst habe ich nicht verstanden, dass Sie es von DOM entfernen wollen. Es funktioniert, danke. – serg

+1

Wenn Sie die Anzeige intakter halten möchten, genügt es, das Attribut 'name' oder' id' zu entfernen - der Knoten selbst kann bleiben. – ecmanaut

2

Es sollte erwartet werden, dass #foo zum Anker der ID "foo" scrollt. Wenn Sie Ansatz 1 verwenden und neu laden möchten, funktioniert dieser Ansatz möglicherweise.

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

Ich konnte es nicht schaffen zu arbeiten. Auch wenn es heilig ist $%^& :) – serg

+0

Ich habe es nie getestet, aber es sollte in jedem großen Browser funktionieren (IE <8 nicht mitgerechnet) und wenn es nicht ist, ist es wahrscheinlich, weil IE nicht erlauben wird, den Deskriptor von neu zu definieren location.hash aus "Sicherheitsgründen" obwohl das ist Stier –

+0

dieser Ansatz funktionierte für mich! komisch – fabio

3

Ich hatte eine JQuery-Funktion, die auf $(document).ready() gezündet, der, wenn es detektiert ein Hash an die URL in meinem Fall angehängt war, so hielt ich diese Funktion gleich und dann verwendet, nur eine Kraft neu laden, wenn ein Hash-Änderung war festgestellt:

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

Dann meine andere Funktion - war

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

In meinem Fall ist es für UX in Ordnung - für andere nicht gut sein könnte.

+1

jQuery bereit Ereignis wird nicht ausgelöst, wenn 'Fenster.location = "#myHash" 'wird ausgeführt, das wäre der Punkt in dieser Frage, glaube ich. Dieser Code ist jedoch zum Laden dynamischer Inhalte nützlich, z. B. wenn die Seite neu geladen wird. – JoeBrockhaus

0

Eine weitere Option ist der Hash-und speichern sie in Sitzungsspeicher zu entfernen, auf reload abgerufen werden:

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

und dann oben auf Ihrer Seite können Sie den folgenden Code haben:

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