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.