window.location.hash = " "; prevent scrolling to the top?
Asked Answered
I

4

26

in my website i set the url adress using

window.location.hash = 'project_name';

but if i want to clean the adress url from any hashes (when i close a project) and i set

window.location.hash = '';

it happens the page scrolls up to the top page

there is any way to clean up the url without any side effect?

thanks

Imalda answered 17/1, 2011 at 15:52 Comment(1)
You could assign a non–existing anchor, but that's not really "cleaning" the URL up :DRouble
A
32

There's the onhashchange event, but it cannot be cancelled reliably across browsers to prevent scrolling. The best solution is to record the scroll position before changing the hash location and reset it afterwards. For example, the following code will catch a click on any link ― that doesn't stop propagation ― with a href value of # and prevent the page from scrolling vertically:

document.onclick = function (evt) {
    var tgt = (evt && evt.target) || event.srcElement,
        scr = document.body.scrollTop;

    if (tgt.tagName == "A" && tgt.href.slice(-1) == "#") {
        window.location.href = "#";
        document.body.scrollTop = scr;           
        return false;
    }
}

If you're changing the hash through script, you can use the following code:

var scr = document.body.scrollTop;
window.location.href = '#';
document.body.scrollTop = scr;

Either of those methods can be adjusted to avoid scrolling individual elements or scrolling the page horizontally. Note that you can remove the entire hash (including the #) without causing navigation or scrolling in modern browsers by calling the pushState or replaceState functions.

Allude answered 17/1, 2011 at 15:56 Comment(6)
You can also temporarily create another element with that id at the scrollTop.Proclivity
fyi,it is not working in Firefox and only most of the time in Chrome. It gets in the ohhashchange function but the browser still scrolls (tried preventing default too).Lightning
@JCarter: you're right, I've removed that part. The other part of my answer is probably the best solution, I've improved on it. Thanks :-)Allude
Take a look at this answer, solved my issue.Mehitable
in 2019 this technique appears not to work in ChromePrincipally
history.pushState(null, null, "#") ended up being the modern solution, however keep in mind this will not trigger hashchange eventPrincipally
J
15

I was having the same problem and came here for an answer. Just found out there is a very easy way:

window.location.hash = ' ';

Basically you are setting it to '# ', since the space doesn't exist, it doesn't move. When you revisit the page, it also doesn't treat it any differently than just #

Janayjanaya answered 19/9, 2012 at 2:14 Comment(1)
This should be the accepted question, in my opinionGiffer
B
8

First off, thanks for your solutions - @Andy-E and @JustMaier.

However, I had a problem getting it to work based on Andy E's second code block in Firefox and JustMaier's code in chrome.

So I did a mash up of those two code blocks and it works just as intended on both browsers

var scr = document.body.scrollTop;

window.location.hash = ' ';

document.body.scrollTop = scr;


My two cents, taking nothing away from the real JS ninjas, mentioned above. : )

Beadledom answered 14/3, 2013 at 7:26 Comment(0)
F
3

document.body.scrollTop is deprecated, also latest Chrome versions seem to be unstable here. The following should work:

  var topPos = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
  window.location.href = '#';
  document.documentElement.scrollTop = topPos;
Flem answered 21/1, 2018 at 10:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.