I have a site at www.tinytoepress.com that uses #hash anchor tag based navigation, using jQuery and the jquery-bbq plugin. It works great, except that sometimes it causes the page to jump down below the header as if it were going to an actual <a name...>
tag. But there are no such tags.
For example, with Chrome on OS X if I visit the homepage:
and then click the "Store" link in the upper left, I go to:
http://www.tinytoepress.com/#store
However, I am scrolled down below the header, which is not desired. I would like to remain right at the top.
If I scroll up and click "About", I go the About page but again I'm scrolled down past the header. However, if I now scroll up to the top and click on "Store" again, I go to Store without scrolling down, which is desired.
I am using simple .show()
and .hide()
methods to controlling the visibility of the div
s which are set from the nav clicks.
Any ideas how to prevent jumping around in the page?
The default browser behaviour when the hash address is changed is to jump to the id that represents the hash. For example: http://example.com/some-page#store
will search on the page the element with id store
(<div id="store">...</div>
). If this is found, the page will jump there.
Instead of setting the id attribute I suggest you to set a custom data-attr
attribute.
<div id="store">...</div>
will become <div data-page="store">...</div>
and in the jQuery side you will replace $(location.hash).show()
with:
$("[data-page='" + location.hash.substring(1) + "']").show()
The code will look like below:
$("a").on("click", function () {
// get the clicked link
var $clickedLink = $(this);
// get the url
var url = $clickedLink.attr("href");
// we search the hashes
if (url[0] !== "#") { return; }
// change the location using js
location.hash= url;
// hide all pages
$("[data-page]").hide();
// show the current page
$("[data-page='" + url.substring(1) + "']").show();
// prevent the default browser behaviour (jumping)
return false;
});