jquerynavigationjquery-bbq

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?


Solution

  • 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