jQuery Logo

jQuery Smooth Scroll to Anchor

Have you ever wanted to smoothly scroll to an anchor on a page with jQuery? The script example I have provided allows several functionalities. If you enter a page with an anchor hash directly, it will smooth scroll to that point on the page. It will also update the hash, and calculate the height of a sticky header or menu.

This works best as an inline script, but does also work when placed inside a JavaScript file.

/**
 * jQuery Smooth Scroll to Anchor
 */
var pauseHashOnChange = false;

// Initialises the Smooth Scroll Functionality
function initSmoothScroll( e, ele ) 
{    
    e.preventDefault();
    url = jQuery( ele ).prop('href');
    hash = url.substring( url.indexOf('#') + 1 );
    hashChange( hash );
}

// Hash Change
function hashChange( hash )
{
    hash = hash ? hash : window.location.hash.slice(1);
    ele = 'a[name=' + hash + ']';

    if ( hash && jQuery( ele ).hasClass('smooth-scroll-target') )
    {
        jQuery( ele ).trigger('click');
        smoothScroll( ele );
    }    
}

// Smooth Scroll
function smoothScroll( ele )
{
    ele = jQuery(ele);
    extraOffset = 30;
    headerOffset = jQuery('header').height();
    offset = headerOffset - extraOffset;

    jQuery('html, body').stop().animate({
        'scrollTop' : ele.offset().top - offset
    }, 900, 'swing', function() {
        pauseHashOnChange = true;
        window.location.hash = ele.prop('name');
        pauseHashOnChange = false;
    });
}

// Run Hash Change onload to trigger the click event and then scroll to the anchor.
jQuery(window).load( function() {
    hashChange();
});

jQuery(document).ready( function($) {
    
    // Listen for Hash Change events.
    $(window).on('hashchange', function() { 
        if ( !pauseHashOnChange )
            hashChange();
    });
    
    // Attach the Smooth Scroll event to a class.
    $('.smooth-scroll').click( function( e ) {
        initSmoothScroll( e, this );
    });
});
<a href="#anchor" class="smooth-scroll">Smooth Scroll</a>
<a name="anchor" class="smooth-scroll-target"></a>