views:

803

answers:

2

I am trying to reload current page with different url hash, but it doesn't work as expected.

(Clarification how I want it to work: Reload the page and then scroll to the new hash.)

Approach #1:

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

Only scrolls to this anchor without reloading the page.

Approach #2:

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

Kinda works but it first scrolls to the anchor, then reloads the page, then scrolls to the anchor again.

Approach #3:

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

Works but I would rather not add random garbage to the url.

Is there a better solution?

+3  A: 

Remove the anchor you're going to navigate to, then use approach #2? Since there's no anchor, setting the hash shouldn't scroll the page.

Nickolay
At first I didn't understand that you mean removing it from DOM. It works, thanks.
serg
+1  A: 

It should be expected that #foo will scroll to the anchor of the id, "foo". If you want to use approach #1 and have it reload, this approach might work.

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)
    });
}
Eli Grey
serg
I never tested it but it should work in every major browser (not counting IE <8) and if it doesn't it's most likely because IE won't allow redefining the descriptor of location.hash for "security reasons" though that's bull
Eli Grey