Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery hash-based nav with jquery-bbq makes page jump around

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:

http://www.tinytoepress.com/

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 divs which are set from the nav clicks.

Any ideas how to prevent jumping around in the page?

like image 840
mrjf Avatar asked Dec 08 '13 23:12

mrjf


2 Answers

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;
});

JSFIDDLE

like image 137
Ionică Bizău Avatar answered Sep 27 '22 21:09

Ionică Bizău


Sorry, can't replicate your issue (running OS X 10.9 with Google Chrome 31.0.1650.63). A possible explanation for your weird jumping: Sometimes the changing content length also plays a role, when loading and inserting new content...

like image 33
Kjell Avatar answered Sep 27 '22 22:09

Kjell