jQuery: Scroll to anchor when calling URL, replace browsers behaviour

Machineghost's answer was very helpful. The code I patched together takes a URL param and turns it into a hash tag that the browser then scrolls to as soon as the DOM is ready.

The URL would look like this:

www.mysite.com/hello/world.htm?page=contact

Contact is the name of the ID you want to scroll to

<h1 id="contact">Contact Us</h1>

Here's the code:

// Get any params from the URL
$.extend({
  getUrlVars: function(){
    var vars = [], hash;
    var url = decodeURIComponent(window.location.href);
    var hashes = url.slice(window.location.href.indexOf('?') + 1).split('&');
    for(var i = 0; i < hashes.length; i++)
    {
      hash = hashes[i].split('=');
      vars.push(hash[0]);
      vars[hash[0]] = hash[1];
    }
    return vars;
  },
  getUrlVar: function(name){
    return $.getUrlVars()[name];
 }
});

$(document).ready(function() {
    // Unhide the main content area
    $('section.centered').fadeIn('slow');

    // Create a var out of the URL param that we can scroll to
    var page = $.getUrlVar('page');
    var scrollElement = '#' + page;

    // Scroll down to the newly specified anchor point
    var destination = $(scrollElement).offset().top;
    $("html:not(:animated),body:not(:animated)").animate({ scrollTop: destination-75}, 800 );
    return false;
});

I checked this in Chrome and FF and it worked very well. Try adjusting "destination-75" if the scroll target isn't going to the exact place you want it to.

I couldn't have done it with out the posts above, so thanks!


I made some enhancement to script from Jan Jongboom so it now looks like this:

$(document).ready(function () {
    // replace # with #_ in all links containing #
    $('a[href*=#]').each(function () {
        $(this).attr('href', $(this).attr('href').replace('#', '#_'));
    });

    // scrollTo if #_ found
    hashname = window.location.hash.replace('#_', '');
    // find element to scroll to (<a name=""> or anything with particular id)
    elem = $('a[name="' + hashname + '"],#' + hashname);

    if(elem) {
         $(document).scrollTo(elem, 800);
    }

});

It changes all anchors in links so for users without javascript the behaviour will remain untouched.


/* scrolling to element */
    var headerHeight = $('#header').height() + $('#header-bottom-cap').height() + 10; //When the header position is fixed
    $('a').click(function(){
        var hashEle = $(this).attr('href').split('#');
        if (hashEle.length > 1) {
            if (hashEle[1] == 'top') {
                $('body, html').animate({
                    scrollTop: 0
                },500);
            } else {
            jQuery('body, html').animate({
                scrollTop: $('#'+ hashEle[1]).offset().top - headerHeight
            },500);
            }
        };
    })
        // find element from url
hashname = window.location.hash.replace('#', '');
elem = $('#' + hashname);
if(hashname.length > 1) {
    if(hashname == 'top') {
    $('body, html').animate({
            scrollTop: 0
        },200); 
    } else {
     $('body, html').animate({
            scrollTop: $(elem).offset().top - headerHeight
        },500);
 }
};
/* END scrolling to element */

this script should be into $(document).ready(function() {});


If you don't create the actual anchor foo, but rather create your anchor with an id like _foo (something like <a id="_foo">). You can handle the $(document).ready to achieve this.

Something like (pseudo code)

$(document).ready(function() { 
    var elem = $('#_' + window.location.hash.replace('#', ''));
    if(elem) {
         $.scrollTo(elem.left, elem.top);
    }
});